blacklisted_maps = { -- List of maps to skip in scans -- North ["l13_generators"] = true, ["l12_stancia_2"] = true, ["l12_stancia"] = true, ["l11_pripyat"] = true, ["l10_radar"] = true, ["l11_hospital"] = true, -- Underground ["jupiter_underground"] = true, ["labx8"] = true, ["l03u_agr_underground"] = true, ["l04u_labx18"] = true, ["l08u_brainlab"] = true, ["l10u_bunker"] = true, ["l12u_control_monolith"] = true, ["l12u_sarcofag"] = true, ["l13u_warlab"] = true, ["fake_start"] = true } --< Tronex > function unlock_note_mysteries_of_the_zone(actor,npc,p) SendScriptCallback("actor_on_interaction", "notes", nil, "mysteries_of_the_zone") end function unlock_note_living_legend(actor,npc,p) SendScriptCallback("actor_on_interaction", "notes", nil, "living_legend") end function unlock_note_mortal_sin(actor,npc,p) SendScriptCallback("actor_on_interaction", "notes", nil, "mortal_sin") end function remove_quest_item(actor,npc,p) if (not p) or (p and #p == 0) then return end local var = load_var(db.actor, p[1]) if (not var) then return end local t = {} if var.item_1_id then t[var.item_1_id] = var.item_1_sec end if var.item_2_id then t[var.item_2_id] = var.item_2_sec end for k,v in pairs(t) do local obj = k and level.object_by_id(k) local se_obj = k and alife_object(k) if se_obj and obj and (obj:section() == v) then alife_release(se_obj) news_manager.relocate_item(db.actor,"out",v,1) end end end function prepare_reward_money(actor,npc,p) -- Prepare money reward to give when actor complete the task -- p[1]: task id -- p[2]: amount of money -- p[3] (optional): maximum amount of money, if this field exists then a random amount of money between p[2] and p[2] will be chosen local var = load_var(db.actor, p[1]) if (not var) then return end local multi = game_difficulties.get_eco_factor("rewards") or 1 local money = tonumber(p[2] or 500) if p[3] then money = math.random(money,tonumber(p[3])) end money = math.ceil(tonumber(money) * multi) var.reward_money = money save_var(db.actor, p[1], var) end function prepare_reward_item(actor,npc,p) -- p[1]: task id -- This function has 3 modes: -- Mode [1] - single item - pattern: (task_id:item) - effect: store item from p[2] - amount: 1 -- Mode [2] - random single item - pattern: (task_id:item_1:item_2:item_3:item_4...) - effect: store an item from a random field (+p[2]) - amount: 1 -- Mode [3] - multi items with defined amount - pattern: (task_id:item_1:amt_1:item_2:amt_2...) - effect: store items p[2],p[4],p[6]... with defined amounts p[3],p[5],p[7]... local var = load_var(db.actor, p[1]) if (not var) then return end -- Set reward mode local mode = 1 if (#p == 2) then mode = 1 -- give one item elseif (#p > 2) and (not tonumber(p[3])) then mode = 2 -- give a random item elseif (#p > 2) and tonumber(p[3]) then mode = 3 -- give a set of items with amount else return end -- Validate sections local function check(sec) if (not ini_sys:section_exist(sec)) then abort("ERROR: Task: %s - Function: prepare_reward_item - Invalid item section found: %s",p[1],sec) end end -- Fill reward table local t = {} if (mode == 1) then check(p[2]) t[p[2]] = 1 elseif (mode == 2) then local pick = p[math.random(2,#p)] check(pick) t[pick] = 1 elseif (mode == 3) then for i=2,#p,2 do local p1 = p[i] local p2 = p[i+1] check(p1) t[p1] = t[p1] and (t[p1] + tonumber(p2)) or tonumber(p2) end end -- stack the old reward table if it exists local t2 = var.reward_item or {} for k,v in pairs(t) do t2[k] = t2[k] and (t2[k] + v) or v end var.reward_item = t2 save_var(db.actor, p[1], var) end function give_reward(actor,npc,p) -- Give stored rewards local var = load_var(db.actor, p[1]) if (not var) then return end -- money reward local money = var.reward_money if money then dialogs.relocate_money(db.actor,money,"in") end -- item reward local items = var.reward_item if items then for k,v in pairs(items) do for i=1,v do local se_item = alife_create_item(k, db.actor) local cls = se_item:clsid() if IsWeapon(nil,cls) or IsOutfit(nil,cls) or IsHeadgear(nil,cls) then --se_item.condition = (math.random(70,90)/100) end end news_manager.relocate_item(db.actor,"in",k,v) end end end function stalker_ceasefire() local blacklist = { ["bandit"] = true, ["monolith"] = true, ["zombied"] = true, ["army"] = true, } local actor_comm = get_actor_true_community() if (not blacklist[actor_comm]) and game_relations.is_factions_enemies("stalker",actor_comm) then game_relations.save_relation ( "stalker" , actor_comm , 2000 ) game_relations.save_relation ( "actor_stalker" , actor_comm , 2000 ) game_relations.save_relation ( "stalker" , "actor_" .. actor_comm , 2000 ) game_relations.send_news ("stalker" , actor_comm , "st_relations_cease_fire" , nil) end end function reward_random_money_by_dist(actor,npc,p) local var = load_var(db.actor, p[1]) local lvl_task = var and var.lvl_task or level.name() local lvl_target = var and var.lvl_target local n = lvl_task and lvl_target and txr_routes.get_shortest_path_num(lvl_task, lvl_target) or 1 local multi = game_difficulties.get_eco_factor("rewards") or 1 local min_val = ( (tonumber(p[2]) or 500) * multi ) / 50 local max_val = ( (tonumber(p[3]) or (min_val + 1000)) * multi ) / 50 local money = math.random( math.ceil(min_val), math.ceil(max_val) ) * 50 local sweets = math.ceil(n * money * tonumber(p[4] or 0.2)) dialogs.relocate_money( db.actor, (money + sweets), "in" ) end local pos_itms = { ["drx_x8_documents"] = {-101.9361038208, -31.361772537231, 90.615669250488, 636, 5090}, ["drx_x16_documents"] = {-46.306594848633, 20.461000442505, 2.1229863166809, 2220, 3792}, ["drx_x18_documents"] = {23.617618560791, -5.6467723846436, -18.183609008789, 6311, 3760}, ["drx_x19_documents"] = {6.817852973938, -7.8305835723877, -15.558134078979, 7638, 3842}, ["drx_agr_u_documents"] = {46.072761535645, 1.8872995376587, 75.970985412598, 3968, 3630}, ["drx_jup_u_documents"] = {27.983295440674, 12.515381813049, -1.1357840299606, 39736, 4861}, ["lx8_history_documents"] = {-93.635635375977, -27.296674728394, 96.18310546875, 1318, 5079}, ["lx8_history_2_documents"] = {-116.10192871094, -27.196212768555, 82.614562988281, 30, 5090}, ["lx8_history_3_documents"] = {-43.184757232666, -19.527189254761, 67.334884643555, 6770, 5094}, ["wpn_gauss_quest"] = {-426.44213867188, 26.069364547729, -383.1135559082, 138111, 4140}, } function spawn_item_at_pos(actor, npc, p) if not (p and p[1]) then return end if (pos_itms[p[1]]) then local pos = vector():set( pos_itms[p[1]][1], pos_itms[p[1]][2], pos_itms[p[1]][3] ) local se_obj = alife_create( p[1], pos, pos_itms[p[1]][4], pos_itms[p[1]][5] ) if (not se_obj) then printe("!ERROR: spawn_item_at_pos | unable to spawn [%s]", p[1]) end else printe("!ERROR: spawn_item_at_pos | no info found for item [%s]", p[1]) end end function give_letter(actor, npc, p) if not (p and ini_sys:section_exist(p[1])) then return end if (not ui_pda_encyclopedia_tab.is_unlocked_note("encyclopedia__notes_" .. p[1])) then alife_create_item(p[1], db.actor) news_manager.relocate_item(db.actor, "in", p[1], 1) end end function increase_rank(actor, npc, p) local value = p[1] and tonumber(p[1]) if value then game_statistics.increment_rank(value) end end function increase_rep(actor, npc, p) local value = p[1] and tonumber(p[1]) if value then game_statistics.increment_reputation(value) end end function decrease_rank(actor, npc, p) local value = p[1] and tonumber(p[1]) if value then game_statistics.increment_rank(-value) end end function decrease_rep(actor, npc, p) local value = p[1] and tonumber(p[1]) if value then game_statistics.increment_reputation(-value) end end function set_task_stage(actor, npc, p) local tm = task_manager.get_task_manager() local task_info = tm.task_info if p and p[1] and p[2] and tm.task_info[p[1]] and tonumber(p[2]) then -- printf('setting task %s stage to %s',p[1],p[2]) task_info[p[1]].stage = tonumber(p[2]) else if p then printf('set_task_stage: arguments incorrect: %s %s',p[1],p[2]) else printf('set_task_stage: no arguments') end end end function open_route(actor, npc, p) if p[1] and p[2] then txr_routes.open_route(p[1],p[2]) end end function snd_volume_off() _G.mus_vol = math.max(get_console_cmd(2,'snd_volume_music'),_G.mus_vol or 0) _G.amb_vol = math.max(get_console_cmd(2,'snd_volume_eff'),_G.amb_vol or 0) exec_console_cmd('snd_volume_music 0') exec_console_cmd('snd_volume_eff 0') end function snd_volume_on() exec_console_cmd('snd_volume_music '..tostring(_G.mus_vol)) exec_console_cmd('snd_volume_eff '..tostring(_G.amb_vol)) end function se_clear_var(actor, npc, p) -- mass clearing for variables that match specific value in server objects, useful for body release tagging if not (p[1] and p[2]) then printe("!ERROR clear_se_var | missing vars: [%s] [%s]", p[1], p[2]) return end local m_data = alife_storage_manager.get_state() for id,v in pairs(m_data.se_object) do if (v[varname] == val) then printf("~se_clear_all_match_var | found match %s = %s in (%s)", varname, val, id) v[varname] = nil end end end --< Tronex > --< MLR > function disable_meet_nimble_info() db.actor:disable_info_portion("actor_meet_nimble_room") end -- Функции для управления мостом. function bridge_down() db.bridge_by_name["red_bridge"]:anim_forward() db.actor:give_info_portion("red_bridge_down_done_2") end function bridge_up() db.bridge_by_name["red_bridge"]:anim_backward() db.actor:disable_info_portion("red_bridge_down_done") db.actor:disable_info_portion("red_bridge_down_done_2") end function bridge_stop() db.bridge_by_name["red_bridge"]:anim_stop() end function anim_obj_down(actor, npc, p) if p[1] ~= nil then db.anim_obj_by_name[p[1]]:anim_forward() end end function anim_obj_up(actor, npc, p) if p[1] ~= nil then db.anim_obj_by_name[p[1]]:anim_backward() end end function anim_obj_stop(actor, npc, p) if p[1] ~= nil then db.anim_obj_by_name[p[1]]:anim_stop() end end function disable_begin_the_battle() db.actor:disable_info_portion("begin_the_battle") end function teleport_for_totaliz_out(first_speaker, second_speaker) local box = get_story_object("bar_arena_inventory_box_2") if (box) then local function transfer_object_item(item) db.actor:transfer_item(item, box) end db.actor:inventory_for_each(transfer_object_item) end xr_zones.purge_arena_items("bar_arena") level.add_pp_effector ("fade_in.ppe", 200, false) db.actor:set_actor_position(vector():set(150.249435424805,0.429966986179352,72.1354370117188),40238,1684) local box = get_story_object("bar_arena_inventory_box") if (box) then local function transfer_object_item(box,item) box:transfer_item(item, db.actor) end box:iterate_inventory_box(transfer_object_item,box) end end function devushka_quest_one_reward(first_speaker, second_speaker) alife_create_item("nomad_outfit", db.actor) alife_create_item("wpn_knife3" , db.actor) alife_create_item("kit_hunt" , db.actor) news_manager.relocate_item(db.actor, "in", "nomad_outfit", 1) news_manager.relocate_item(db.actor, "in", "wpn_knife3" , 1) news_manager.relocate_item(db.actor, "in", "kit_hunt" , 1) end --< MLR > --< LTTZ > function spawn_strelok_notes() local pos = vector():set( 43.601459503174, 1.3544018268585, 75.227851867676 ) local se_obj = alife_create( "strelok_notes", pos, 3762, 3630 ) if ( not se_obj ) then printe("!ERROR: unable to spawn strelok_notes" ) end end function spawn_wpn_gauss_quest() -- not used -- Potential locations for quest item: local quest_item_locations_list = { {-421.80874633789, 23.745666503906, -328.25729370117, 145096, 4394}, -- location data for location 1 {-411.07214355469, 32.196994781494, -334.24200439453, 161488, 4139}, -- location data for location 2 {-424.48648071289, 24.198583602905, -381.48046875, 142021, 4140}, -- location data for location 3 } -- Choose random location from the list: local i = math.random( #quest_item_locations_list ) -- Set the position vector with the x, y, and z coordinates: local pos = vector():set( quest_item_locations_list[i][1], quest_item_locations_list[i][2], quest_item_locations_list[i][3] ) -- Extract the level vertex id for the chosen location: local lvid = quest_item_locations_list[i][4] -- Extract the game vertex id: local gvid = quest_item_locations_list[i][5] -- Spawn the item at the chosen location: local se_obj = alife_create( "wpn_gauss_quest", pos, lvid, gvid ) if ( not se_obj ) then printe("!ERROR: unable to spawn wpn_gauss_quest" ) end end function lttz_ll_take_wpn_gauss_quest(actor, npc) remove_item(actor, npc, {"wpn_gauss_quest"}) end function lttz_ll_take_strelok_notes(actor, npc) remove_item(actor, npc, {"strelok_notes"}) dialogs.relocate_item_section(second_speaker, "af_glass_af_aam", "in",1) inc_faction_goodwill_to_actor(db.actor, nil, {"stalker", 50}) end function spawn_x8_documents() -- Potential locations for quest item: local quest_item_locations_list = { {-79.236862182617, -24.324705123901, 89.061508178711, 3417, 5077}, -- location data for location 1 {-101.86143493652, -31.362953186035, 90.774269104004, 636, 5090}, -- location data for location 2 {-79.810501098633, -15.038819313049, 114.17692565918, 3459, 5098}, -- location data for location 3 } -- Choose random location from the list: local i = math.random( #quest_item_locations_list ) -- Set the position vector with the x, y, and z coordinates: local pos = vector():set( quest_item_locations_list[i][1], quest_item_locations_list[i][2], quest_item_locations_list[i][3] ) -- Extract the level vertex id for the chosen location: local lvid = quest_item_locations_list[i][4] -- Extract the game vertex id: local gvid = quest_item_locations_list[i][5] -- Spawn the item at the chosen location: local se_obj = alife_create( "x8_documents", pos, lvid, gvid ) if ( not se_obj ) then printe("!ERROR: unable to spawn x8_documents" ) end end function spawn_monolith_shard() local pos = vector():set( 0.072339810431004, -34.356998443604, 17.800102233887 ) local se_obj = alife_create( "monolith_shard", pos, 1849, 4055 ) if ( not se_obj ) then printe("!ERROR: unable to spawn monolith_shard" ) end end function lttz_ll_take_x8_documents(actor, npc) remove_item(actor, npc, {"x8_documents"}) end function lttz_ll_give_wpn_gauss_quest(first_speaker, second_speaker) dialogs.relocate_item_section(second_speaker, "wpn_gauss_quest", "in",1) end function lttz_ll_give_gauss_ammo(first_speaker, second_speaker) dialogs.relocate_item_section(second_speaker, "ammo_gauss", "in",2) end function lttz_ll_take_monolith_shard(actor, npc) remove_item(actor, npc, {"monolith_shard"}) end function lttz_ll_give_strelok_pendrive(first_speaker, second_speaker) dialogs.relocate_item_section(second_speaker, "strelok_pendrive", "in",1) end function lttz_ll_take_strelok_pendrive(actor, npc) remove_item(actor, npc, {"strelok_pendrive"}) end function lttz_ll_give_doctor_artefact(first_speaker, second_speaker) dialogs.relocate_item_section(second_speaker, "af_mincer_meat_af_aam", "in",1) inc_faction_goodwill_to_actor(db.actor, nil, {"stalker", 50}) end function spawn_stitch_decoder() -- Potential locations for quest item: local quest_item_locations_list = { {50.247924804688, 3.9755771160126, 156.77543640137, 509188, 5248}, -- location data for location 1 {51.563461303711, 7.1993789672852, 224.42543029785, 514950, 5155}, -- location data for location 2 {19.012723922729, 1.1766533851624, 112.65353393555, 472104, 5144}, -- location data for location 3 } -- Choose random location from the list: local i = math.random( #quest_item_locations_list ) -- Set the position vector with the x, y, and z coordinates: local pos = vector():set( quest_item_locations_list[i][1], quest_item_locations_list[i][2], quest_item_locations_list[i][3] ) -- Extract the level vertex id for the chosen location: local lvid = quest_item_locations_list[i][4] -- Extract the game vertex id: local gvid = quest_item_locations_list[i][5] -- Spawn the item at the chosen location: local se_obj = alife_create( "stitch_decoder", pos, lvid, gvid ) if se_obj then item_radio.add_target(se_obj.id, 171, 75) else printe("!ERROR: unable to spawn stitch_decoder" ) end end function lttz_ms_take_stitch_decoder(actor, npc) remove_item(actor, npc, {"stitch_decoder"}) end function lttz_ms_take_attackers_pda(actor, npc) remove_item(actor, npc, {"attackers_pda"}) end function create_special_task_squad(actor,npc,p) level.add_pp_effector("black.ppe", 1500, false) create_squad(actor,npc,p) end function spawn_contact_lost_pda() -- Potential locations for quest item: local quest_item_locations_list = { {-35.871238708496, -4.0057287216187, 139.02619934082, 8109, 2458}, -- location data for location 1 {-18.989786148071, -3.9511435031891, 143.22698974609, 15620, 2477}, -- location data for location 2 {-24.930610656738, -4.015763759613, 139.54330444336, 12734, 2458}, -- location data for location 3 } -- Choose random location from the list: local i = math.random( #quest_item_locations_list ) -- Set the position vector with the x, y, and z coordinates: local pos = vector():set( quest_item_locations_list[i][1], quest_item_locations_list[i][2], quest_item_locations_list[i][3] ) -- Extract the level vertex id for the chosen location: local lvid = quest_item_locations_list[i][4] -- Extract the game vertex id: local gvid = quest_item_locations_list[i][5] -- Spawn the item at the chosen location: local se_obj = alife_create( "contact_lost_pda", pos, lvid, gvid ) if ( not se_obj ) then printe("!ERROR: unable to spawn contact_lost_pda" ) end end function lttz_ms_take_contact_lost_pda(actor, npc) remove_item(actor, npc, {"contact_lost_pda"}) end function gen_stitch_message() local msg = game.translate_string("st_lttz_gen_stitch_message") local sender = game.translate_string("st_dyn_news_anonymous") db.actor:give_game_news(sender, msg, "ui_inGame2_Radiopomehi", 0, 20000) xr_sound.set_sound_play(AC_ID, "pda_task") end function premature_emission(actor, npc) level.set_weather_fx("fx_surge_day_3_stancia") this.aes_earthshake(npc) end function lttz_oa_give_decryption_radio(first_speaker, second_speaker) dialogs.relocate_item_section(second_speaker, "decryption_radio", "in",1) end function lttz_ll_take_zat_b40_sarge_pda(actor, npc) remove_item(actor, npc, {"zat_b40_sarge_pda"}) end function lttz_oa_take_decryption_radio(actor, npc) remove_item(actor, npc, {"decryption_radio"}) end function intercepted_transmission() local msg = game.translate_string("st_lttz_intercepted_transmission_message") local name = game.translate_string("st_dyn_news_unknown_contact") db.actor:give_game_news(name, msg, "ui_inGame2_Radiopomehi", 0, 12000) xr_sound.set_sound_play(AC_ID, "pda_task") end function set_squad_enemy_lttz(actor, npc, p) local story_id = p[1] local squad = get_story_squad(story_id) if squad == nil then printf("There is no squad with id[%s]", tostring(story_id)) return end squad:force_set_goodwill(-5000, actor) end function yanov_invitation() local msg = game.translate_string("st_lttz_yanov_invitation_message") local name = game.translate_string("army_degtyarev_jup_name") local comm = game.translate_string("st_dyn_news_comm_stalker_6") local se = strformat("%s, %s",name,comm) db.actor:give_game_news(se, msg, "ui_inGame2_Hero", 0, 20000) xr_sound.set_sound_play(AC_ID, "pda_task") end function yanov_invitation2() local msg = game.translate_string("st_lttz_yanov_invitation2_message") local name = game.translate_string("army_degtyarev_jup_name") local comm = game.translate_string("st_dyn_news_comm_stalker_6") local se = strformat("%s, %s",name,comm) db.actor:give_game_news(se, msg, "ui_inGame2_Hero", 0, 20000) xr_sound.set_sound_play(AC_ID, "pda_task") end function lttz_oa_give_special_delivery_case(first_speaker, second_speaker) dialogs.relocate_item_section(second_speaker, "special_delivery_case", "in",1) end function lttz_oa_take_special_delivery_case(actor, npc) remove_item(actor, npc, {"special_delivery_case"}) end function lttz_oa_give_army_isg_spy_pendrive(first_speaker, second_speaker) dialogs.relocate_item_section(second_speaker, "army_isg_spy_pendrive", "in",1) end function lttz_oa_take_army_isg_spy_pendrive(actor, npc) remove_item(actor, npc, {"army_isg_spy_pendrive"}) end function spawn_jupiter_documents( ) -- Potential locations for quest item: local quest_item_locations_list = { {304.7744140625, 28.783397674561, -299.32592773438, 1209997, 4517}, -- location data for location 1 {324.68350219727, 31.384368896484, -305.80865478516, 1235548, 4517}, -- location data for location 2 {351.95175170898, 27.543346405029, -343.99871826172, 1276714, 4516}, -- location data for location 3 } -- Choose random location from the list: local i = math.random( #quest_item_locations_list ) -- Set the position vector with the x, y, and z coordinates: local pos = vector( ):set( quest_item_locations_list[i][1], quest_item_locations_list[i][2], quest_item_locations_list[i][3] ) -- Extract the level vertex id for the chosen location: local lvid = quest_item_locations_list[i][4] -- Extract the game vertex id: local gvid = quest_item_locations_list[i][5] -- Spawn the item at the chosen location: local se_obj = alife_create("jupiter_documents", pos, lvid, gvid ) if ( not se_obj ) then printe("!ERROR: unable to spawn jupiter_documents" ) end end function lttz_oa_take_jupiter_documents(actor, npc) remove_item(actor, npc, {"jupiter_documents"}) end function pripyat_strelok_message() local msg = game.translate_string("st_lttz_pripyat_strelok_message") local name = game.translate_string("stalker_strelok_oa_name") local comm = game.translate_string("st_dyn_news_comm_stalker_6") local se = strformat("%s, %s",name,comm) db.actor:give_game_news(se, msg, "ui_inGame2_strelok_ico", 0, 20000) xr_sound.set_sound_play(AC_ID, "pda_task") end function pripyat_rogue_message() local msg = game.translate_string("st_lttz_pripyat_rogue_message") local name = game.translate_string("stalker_rogue_oa_name") local comm = game.translate_string("st_dyn_news_comm_stalker_6") local se = strformat("%s, %s",name,comm) db.actor:give_game_news(se, msg, "ui_inGame2_neutral_2_merc", 0, 20000) xr_sound.set_sound_play(AC_ID, "pda_task") end function lttz_oa_take_drug_psy_blockade(actor, npc) remove_item(actor, npc, {"drug_psy_blockade"}) end function pripyat_stitch_message() local msg = game.translate_string("st_lttz_pripyat_stitch_message") local name = game.translate_string("stalker_stitch_oa_name") local comm = game.translate_string("st_dyn_news_comm_stalker_6") local se = strformat("%s, %s",name,comm) db.actor:give_game_news(se, msg, "ui_inGame2_neutral_2_mask", 0, 20000) xr_sound.set_sound_play(AC_ID, "pda_task") end function pripyat_degtyarev_message() local msg = game.translate_string("st_lttz_pripyat_degtyarev_message") local name = game.translate_string("army_degtyarev_name") local comm = game.translate_string("st_dyn_news_ssu") local se = strformat("%s, %s",name,comm) db.actor:give_game_news(se, msg, "ui_inGame2_Hero", 0, 30000) xr_sound.set_sound_play(AC_ID, "pda_task") end function pripyat_strelok_message2() local msg = game.translate_string("st_lttz_pripyat_strelok_message2") local name = game.translate_string("stalker_strelok_oa_name") local comm = game.translate_string("st_dyn_news_comm_stalker_6") local se = strformat("%s, %s",name,comm) db.actor:give_game_news(se, msg, "ui_inGame2_strelok_ico", 0, 30000) xr_sound.set_sound_play(AC_ID, "pda_task") end function pripyat_unisg_message() local msg = game.translate_string("st_lttz_pripyat_unisg_message") local name = game.translate_string("st_dyn_news_unknown_contact") db.actor:give_game_news(name, msg, "ui_inGame2_neutral_4", 0, 20000) xr_sound.set_sound_play(AC_ID, "pda_task") end --< LTTZ > --< DRX > function drx_sl_meet_random_honcho( actor, npc, p ) -- Give actor meet honcho task: -- Description: Finds a random friendly honcho and creates task to meet -- Usage: drx_sl_meet_random_honcho() -- Parameters: none -- Return value (type: none): none, creates task for player to meet next honcho -- List of honchos and their surrounding factions: local drx_sl_honchos_table = axr_task_manager.drx_sl_honchos_table -- Create list of valid honchos: local honcho_list = {} local size_t = 0 -- Examine each honcho: for i = 1, #drx_sl_honchos_table do -- Get the current honcho id: local honcho = drx_sl_honchos_table[i][1] -- Check if honcho is alive and is not current task giver: if ( ((xr_conditions.is_alive( nil, nil, {honcho} )) or (honcho == "esc_m_trader")) and (honcho ~= load_var( db.actor, "drx_sl_current_honcho", "" )) ) then -- Check if the honcho surrounding factions are not enemy of player: local is_enemy = false for j = 2, #drx_sl_honchos_table[i] do if ( relation_registry.community_relation( drx_sl_honchos_table[i][j], alife():actor():community() ) <= -1000 ) then is_enemy = true end end -- Add the current honcho to the list of valid honchos: if ( is_enemy == false ) then size_t = size_t + 1 honcho_list[size_t] = honcho end end end -- Pick next honcho: local next_honcho = load_var( db.actor, "drx_sl_current_honcho", "" ) if ( size_t > 0 ) then next_honcho = honcho_list[math.random( size_t )] end save_var( db.actor, "drx_sl_current_honcho", next_honcho ) -- Increment current task number: save_var( db.actor, "drx_sl_current_task_number", (load_var( db.actor, "drx_sl_current_task_number", 1 ) + 1) ) printf( ("DRX SL task count: " .. load_var( db.actor, "drx_sl_current_task_number", 1 )) ) -- Build list of available meet current honcho tasks: task_ltx_file = task_manager.task_ini local honcho_task_list = {} size_t = 0 local honcho_task_id = "" local i = 1 while ( true ) do honcho_task_id = ("drx_sl_" .. next_honcho .. "_meet_task_" .. i) if ( task_ltx_file:section_exist( honcho_task_id ) ) then size_t = size_t + 1 honcho_task_list[size_t] = honcho_task_id i = (i + 1) else break end end -- Give player meet next honcho task: if ( size_t > 0 ) then honcho_task_id = honcho_task_list[math.random( size_t )] save_var( db.actor, "drx_sl_current_task", honcho_task_id ) printf( ("DRX SL current storyline task: " .. honcho_task_id) ) give_info( ("drx_sl_meet_honcho_" .. next_honcho) ) -- (\configs\gameplay\info_portions.xml) task_manager.get_task_manager():give_task( honcho_task_id ) else printf( ("DRX SL no meet honcho tasks available for " .. next_honcho .. " !!") ) return end end function drx_sl_change_factions( actor, npc, p ) -- Change actor faction: -- Description: Changes an actor to the specified faction -- Usage: drx_sl_change_factions( faction ) -- Parameters: -- faction (type: string) Faction for the actor to join (stalker, dolg, freedom, csky, ecolog, killer, army, bandit, or monolith) -- Return value (type: none): none if ( p and p[1] ~= nil and p[1] ~= ("actor_" .. character_community( db.actor )) ) then -- Set actor faction: set_actor_true_community(p[1]) local communities = utils_obj.get_communities_list() -- for i, community in pairs( communities ) do -- relation_registry.set_community_goodwill( community, AC_ID, 0 ) -- end printf( ("DRX SL: Actor faction changed to " .. p[1]) ) --[[ Set companion faction: for id, squad in pairs( axr_companions.companion_squads ) do if ( squad and squad.commander_id ) then for k in squad:squad_members() do local member = db.storage[k.id] and db.storage[k.id].object if ( member and member:alive() ) then member:set_character_community( p[1], 0, 0 ) for i, community in pairs( communities ) do member:set_community_goodwill( community, 0 ) end printf( ("DRX SL: Companion faction changed to " .. p[1]) ) end end end end -]] -- Send dynamic news alert: news_manager.send_tip( db.actor, (game.translate_string( "st_drx_questlines_joined" ) .. " " .. game.translate_string( p[1] ) .. " " .. game.translate_string( "st_drx_questlines_faction" )), nil, "completionist", nil, nil ) end end function drx_sl_setup_questlines( actor, npc, p ) local faction = p and p[1] if (not faction) then printe("! ERROR drx_sl_setup_questlines | no faction defined") return end -- Determine total number of storyline tasks to complete for this game: save_var( db.actor, "drx_sl_total_task_number", math.random( 8, 12 ) ) -- Set to range of total meet honcho tasks to complete to finish game save_var( db.actor, "drx_sl_current_task_number", 1 ) -- Determine first honcho to start at: local honcho_table = axr_task_manager.drx_sl_main_honcho_table local start_game_honcho = honcho_table[faction] or "" if (not honcho_table[faction]) then printf( "DRX SL no available game start honchos !!" ) end -- Build list of available start game versions for start game honcho: honcho_start_ltx_file = task_manager.task_ini local honcho_start_list = {} local honcho_start_id = "" local i = 1 while ( true ) do honcho_start_id = ("drx_sl_" .. start_game_honcho .. "_start_game_" .. i) if ( honcho_start_ltx_file:section_exist( honcho_start_id ) ) then table.insert( honcho_start_list, honcho_start_id ) i = (i + 1) else break end end -- Send actor to start game at current honcho: if ( #honcho_start_list > 0 ) then math.randomseed( device( ):time_global( ) ) honcho_start_id = honcho_start_list[math.random( #honcho_start_list )] printf( ("DRX SL current storyline task: " .. honcho_start_id) ) save_var( db.actor, "drx_sl_start_task", honcho_start_id ) save_var( db.actor, "drx_sl_current_honcho", start_game_honcho ) give_info( ("drx_sl_start_game_" .. start_game_honcho) ) -- (\configs\gameplay\info_portions.xml) --task_manager.get_task_manager( ):give_task( honcho_start_id ) printf( "DRX questlines are successfuly set for [%s] faction", faction ) else printf( ("DRX SL no start game tasks available for " .. start_game_honcho .. " !!") ) end end function drx_sl_cancel_questlines( actor, npc, p ) -- Cancel all DRX questlines, and disabled info portion for them save_var( db.actor, "drx_sl_start_task", nil ) save_var( db.actor, "drx_sl_current_honcho", nil ) save_var( db.actor, "drx_sl_current_task_number", nil ) save_var( db.actor, "drx_sl_current_task", nil ) save_var( db.actor, "drx_sl_total_task_number", nil ) save_var( db.actor, "drx_sl_current_task_number", nil ) local drx_sl_honchos_table = axr_task_manager.drx_sl_honchos_table local task_cfg = axr_task_manager.CFG_CACHE local tm = task_manager.get_task_manager() local task_info = tm.task_info -- Disable active info for DRX honcho for i = 1, #drx_sl_honchos_table do local honcho = drx_sl_honchos_table[i][1] if has_alife_info("drx_sl_meet_honcho_" .. honcho) then disable_info("drx_sl_meet_honcho_" .. honcho) end end -- Cancel active DRX tasks for task_id,tbl in pairs(task_info) do if starts_with(task_id, "drx_sl_") then tbl.forced_status = "fail" tbl.cancelled_by_actor = true end end end function drx_sl_money_task_payment( actor, npc, p ) -- Take money task payment: -- Description: Takes payment from actor for a money task -- Usage: drx_sl_money_task_payment( task_id_var ) -- Parameters: -- task_id_var (type: string) Var used for money task payment amount -- Return value (type: none): none if ( p and p[1] ~= nil ) then local money = tonumber( load_var( db.actor, p[1], 0 ) ) db.actor:give_money( -(money) ) --game_stats.money_quest_update( -(money) ) news_manager.relocate_money( db.actor, "out", money ) end end function drx_sl_find_wish_granter( actor, npc, p ) -- Give actor find Wish Granter task: -- Description: Gives task to find the Wish Granter -- Usage: drx_sl_meet_random_honcho() -- Parameters: none -- Return value (type: none): none local wish_granter_task = "drx_sl_find_wish_granter_task" save_var( db.actor, "drx_sl_current_task", wish_granter_task ) printf( ("DRX SL current storyline task: " .. wish_granter_task) ) give_info( "drx_sl_on_find_wish_granter" ) -- (\configs\gameplay\info_portions.xml) task_manager.get_task_manager():give_task( wish_granter_task ) end function drx_sl_reward_random_rifle( actor, npc, p ) -- Give actor random rifle reward: -- Description: Gives actor a random reward of a rifle within a specified value -- Usage: drx_sl_reward_random_rifle( p[1]:p[2] ) -- Parameters: -- p[1] (type: int) Minimum value of the reward -- p[2] (type: int) Maximum value of the reward -- Return value (type: none): none, allocates reward to actor -- List of reward items: local reward_items = { -- -------------------------------------------- -- Tier 1 (1 - 99): "wpn_bm16", -- [1] 200 -- -------------------------------------------- -- Tier 2 (100 - 999): "wpn_toz34", -- [2] 1200 -- -------------------------------------------- -- Tier 3 (1000 - 1999): "wpn_wincheaster1300", -- [3] 2400 "wpn_ak74u", -- [4] 3000 "wpn_mp5", -- [5] 3600 "wpn_ak74", -- [6] 4000 -- -------------------------------------------- -- Tier 4 (2000 - 2999): "wpn_l85", -- [7] 5000 "wpn_spas12", -- [8] 5300 "wpn_abakan", -- [9] 6000 "wpn_lr300", -- [10] 6000 -- -------------------------------------------- -- Tier 5 (3000 - 3999): "wpn_sig550", -- [11] 8000 -- -------------------------------------------- -- Tier 6 (4000 - 4999): "wpn_protecta", -- [12] 9000 "wpn_val", -- [13] 9000 -- -------------------------------------------- -- Tier 7 (5000 - 5999): "wpn_g36", -- [14] 10000 "wpn_groza", -- [15] 10000 -- -------------------------------------------- -- Tier 8 (6000 - 6999): "wpn_vintorez", -- [16] 12000 -- -------------------------------------------- -- Tier 9 (7000 - 7999): "wpn_fn2000", -- [17] 14000 "wpn_svd", -- [18] 16000 -- -------------------------------------------- -- Tier 10 (8000 - 8999): "wpn_svu", -- [19] 17000 -- -------------------------------------------- -- Tier 11 (9000 - 9999): "wpn_pkm", -- [20] 20000 "wpn_rg-6", -- [21] 20000 -- -------------------------------------------- -- Tier 12 (10000+): "wpn_rpg7" -- [22] 26000 } local reward_tbl = { -- Tiers [100] = 2, [1000] = 3, [2000] = 7, [3000] = 11, [4000] = 12, [5000] = 14, [6000] = 16, [7000] = 17, [8000] = 19, [9000] = 20, [10000] = 22, } -- Find tier bottom for minimum reward: local min_reward_value = tonumber( p[1] ) local min_reward_no = 1 local functor = function(t,a,b) return a < b end for val,no in spairs(reward_tbl,functor) do if min_reward_value >= val then min_reward_no = no end end -- Find tier top for maximum reward: local max_reward_value = tonumber( p[2] ) local max_reward_no = 22 local functor2 = function(t,a,b) return a > b end for val,no in spairs(reward_tbl,functor2) do if ( max_reward_value < val ) then max_reward_no = no - 1 end end -- Give actor rifle reward: dialogs.relocate_item_section( db.actor, reward_items[math.random( min_reward_no, max_reward_no )], "in" ) end function drx_sl_reward_random_artefact( actor, npc, p ) -- Give actor random artefact reward: -- Description: Gives actor a random reward of an artefact within a specified value -- Usage: drx_sl_reward_random_artefact( p[1]:p[2] ) -- Parameters: -- p[1] (type: int) Minimum value of the reward -- p[2] (type: int) Maximum value of the reward -- Return value (type: none): none, allocates reward to actor -- List of reward items: local reward_items = { -- Tier 1 "af_itcher", "af_blood", "af_electra_sparkler", "af_cristall_flower", "af_medusa", "af_night_star", "af_dummy_glassbeads", "af_dummy_battery", "af_soul", -- Tier 2 "af_pin", "af_mincer_meat", "af_sponge", "af_lobster_eyes", "af_vyvert", "af_cristall", "af_bracelet", "af_ring", "af_electra_moonlight", "af_empty", "af_gravi", "af_eye", "af_dummy_dummy", "af_fuzz_kolobok", -- Tier 3 "af_fireball", "af_baloon", "af_electra_flash", "af_black_spray", "af_full_empty", "af_gold_fish", "af_fire", "af_ice", "af_glass", } local reward_tbl = { -- Money <-> Artefact index [4000] = 5, [5000] = 9, [6000] = 14, [7000] = 15, [9000] = 19, [10000] = 20, [15000] = 23, [20000] = 27, [25000] = 32, } -- Find tier bottom for minimum reward: local min_reward_value = tonumber( p[1] ) local min_reward_no = 1 local functor = function(t,a,b) return a < b end for val,no in spairs(reward_tbl,functor) do if min_reward_value >= val then min_reward_no = no end end -- Find tier top for maximum reward: local max_reward_value = tonumber( p[2] ) local max_reward_no = 24 local functor2 = function(t,a,b) return a > b end for val,no in spairs(reward_tbl,functor2) do if ( max_reward_value < val ) then max_reward_no = no - 1 end end -- Give actor artefact reward: dialogs.relocate_item_section( db.actor, reward_items[math.random( min_reward_no, max_reward_no )], "in" ) end function drx_sl_reset_stored_task( actor, npc, p ) -- Reset stored task for current NPC: -- -- drx_sl_reset_stored_task function -- Description: Removes a stored NPC task -- Usage: drx_sl_reset_stored_task( [p1] ) -- Parameters: -- p[1] (type: string) -- - Task ID of finished task given by the task giver to unregister -- Return value (type: none): none -- Get task giver id: if ( (#p < 1) or (not p[1]) ) then return end local tm = task_manager.get_task_manager() local task_info = tm.task_info local giver_id = task_info[p[1]].task_giver_id -- Reset stored task: if ( giver_id ) then save_var( db.actor, ("drx_sl_npc_stored_task_" .. giver_id), nil ) end end function drx_sl_unregister_task_giver( actor, npc, p ) -- Unregister current task giver: -- Description: Unregisters a task giver as current -- Usage: drx_sl_unregister_task_giver( [p1] ) -- Parameters: -- p[1] (type: string) -- - Task ID given by the task giver to unregister -- Return value (type: none): none -- Validate input parameters: if ( (#p < 1) or (not p[1]) ) then return end printf( ("DRX SL task ended: " .. p[1]) ) -- Get task giver id: local tm = task_manager.get_task_manager() local task_info = tm.task_info local giver_id = task_info[p[1]].task_giver_id -- Unregister task giver: if ( giver_id and not string.find( "meet_task", p[1] ) ) then local giver_task_count = (load_var( db.actor, ("drx_sl_task_giver_" .. giver_id), 0 ) - 1) if ( giver_task_count < 0 ) then giver_task_count = 0 end save_var( db.actor, ("drx_sl_task_giver_" .. giver_id), giver_task_count ) printf( ("DRX SL: drx_sl_task_giver_" .. giver_id .. " unregistered (" .. giver_task_count .. " outstanding)") ) end end function drx_sl_unregister_hostage_giver( actor, npc, p ) -- Unregister current hostage task giver: -- Description: Unregisters a hostage task giver as current -- Usage: drx_sl_unregister_hostage_giver( [p1] ) -- Parameters: -- p[1] (type: string) Task ID given by the task giver to unregister -- Return value (type: none): none -- Validate input parameters: if ( (#p < 1) or (not p[1]) ) then return end -- Get task giver id: local tm = task_manager.get_task_manager() local task_info = tm.task_info local giver_id = task_info[p[1]].task_giver_id -- Unregister task giver: if ( giver_id ) then save_var( db.actor, ("drx_sl_hostage_giver_" .. giver_id), false ) printf( ("DRX SL: drx_sl_hostage_giver_" .. giver_id .. " unregistered") ) end end function drx_sl_decrease_sl_tasks_count( actor, npc, p ) -- Decrease number of completed storyline tasks: -- Description: Decreases the number of completed storyline tasks -- Usage: drx_sl_decrease_sl_tasks_count() -- Parameters: none -- Return value (type: none): none -- Get the current task count: local task_count = load_var( db.actor, "drx_sl_current_task_number", 1 ) -- Decrement the current task count: task_count = (task_count - 1) if ( task_count < 1 ) then task_count = 1 end -- Save the current task count: save_var( db.actor, "drx_sl_current_task_number", task_count ) printf( "DRX SL: player failed last storyline task, decrementing drx_sl_current_task_number" ) printf( ("DRX SL task count: " .. task_count) ) end --< DRX > -- ---------------------------------------------------------------------------------------------------- -- Общие функции -- ---------------------------------------------------------------------------------------------------- -- TODO: Remove all unused COP story functions local DIALOG_LAST_ID = nil --------------------------------------------------------------------------------------------------------------- function inc_task_stage(actor,npc,p) local tsk = p[1] and task_manager.get_task_manager().task_info[p[1]] if (tsk and tsk.stage) then --printf("inc_task_stage=%s stage=%s",p[1],tsk.stage) tsk.stage = tsk.stage + 1 end end function dec_task_stage(actor,npc,p) local tsk = p[1] and task_manager.get_task_manager().task_info[p[1]] if (tsk and tsk.stage) then tsk.stage = tsk.stage - 1 end end function set_smart_faction(actor,npc,p) local smart = p and p[1] and SIMBOARD.smarts_by_names[p[1]] if not (smart) then return false end smart.faction = p[2] end function fail_task_dec_goodwill(actor,npc,p) local multi = game_difficulties.get_eco_factor("goodwill") or 1 local amt = tonumber(p[1])*multi or 50 for i=2,#p do inc_faction_goodwill_to_actor(db.actor, nil, {p[i], -(amt), true}) end end -- Goodwill function complete_task_inc_goodwill(actor,npc,p) -- param1 - amount of goodwill to increase -- param2+ - community local multi = game_difficulties.get_eco_factor("goodwill") or 1 local amt = tonumber(p[1])*multi or 50 for i=2,#p do inc_faction_goodwill_to_actor(db.actor, nil, {p[i], amt, true}) end end function inc_goodwill_by_tasker_comm(actor,npc,p) -- param1 - task_id -- param2 - amount of goodwill to increase if not (p and p[1] and p[2]) then return end local var = load_var(db.actor, p[1]) local comm = var and var.task_giver_comm if (not comm) and db.actor:is_talking() then local speaker = mob_trade.GetTalkingNpc() comm = character_community(speaker) end if (not comm) then printe("! ERROR %s | no community could be gathered") return end comm = (comm == "trader") and "stalker" or comm local multi = game_difficulties.get_eco_factor("goodwill") or 1 local amt = tonumber(p[2])*multi or 50 inc_faction_goodwill_to_actor(db.actor, nil, {comm, amt, true}) end function inc_goodwill_by_tasker_id(actor,npc,p) -- param1 - task_id -- param2 - amount of goodwill to increase if not (p and p[1] and p[2]) then return end local tm = task_manager.get_task_manager() local task_info = tm.task_info local giver_id = task_info[p[1]].task_giver_id local npc = giver_id and db.storage[giver_id] and db.storage[giver_id].object if npc then local comm = character_community(npc) comm = (comm == "trader") and "stalker" or comm local multi = game_difficulties.get_eco_factor("goodwill") or 1 local amt = tonumber(p[2])*multi or 50 inc_faction_goodwill_to_actor(db.actor, nil, {comm, amt, true}) end end function dec_goodwill_by_tasker_id(actor,npc,p) -- param1 - task_id -- param2 - amount of goodwill to increase if not (p and p[1] and p[2]) then return end local tm = task_manager.get_task_manager() local task_info = tm.task_info local giver_id = task_info[p[1]].task_giver_id local npc = giver_id and db.storage[giver_id] and db.storage[giver_id].object if npc then local comm = character_community(npc) comm = (comm == "trader") and "stalker" or comm local multi = game_difficulties.get_eco_factor("goodwill") or 1 local amt = tonumber(p[2])*multi or 50 inc_faction_goodwill_to_actor(db.actor, nil, {comm, -(amt), true}) end end function reward_money(actor,npc,p) local multi = game_difficulties.get_eco_factor("rewards") or 1 dialogs.relocate_money(db.actor,tonumber(p[1] or 500)*multi,"in") end function reward_stash(actor,npc,p) if (p and p[1] ~= "true") or ((math.random(1,100)/100) <= 0.5) then local bonus if ((math.random(1,100)/100) <= 0.5) then local stash_bonus = treasure_manager.stash_bonus if stash_bonus and (#stash_bonus > 0) then bonus = {stash_bonus[math.random(#stash_bonus)]} end end --[[ if ((math.random(1,100)/100) <= 0.1) then local t = {"itm_basickit","itm_advancedkit","itm_expertkit","itm_drugkit","itm_ammokit"} bonus = {t[math.random(#t)]} end --]] treasure_manager.create_random_stash(nil,nil,bonus, true) end end function reward_item_cost_mult_and_remove(actor,npc,p) local sec = load_var(db.actor,p[1]) if not (sec) then return end local item = db.actor:object(sec) if not (item) then return end local cond = 1 if (item:condition()) then cond = item:condition() end local multi = game_difficulties.get_eco_factor("rewards") or 1 -->> dialogs.relocate_money(db.actor, math.floor((tonumber(p[2]) or 1)*item:cost()*cond*cond*cond*multi) ,"in") remove_item(actor, npc, {sec,p[3]}) end function reward_item(actor,npc,p) if p and p[1] then local section_d = p[1] -- See if it's specific uses local section, uses = utils_item.get_defined_uses(section_d) if (section ~= "" and ini_sys:section_exist(section)) then local se_item = alife_create_item(section, db.actor) if se_item then local cls = se_item:clsid() if (IsWeapon(nil,cls) and cls ~= clsid.wpn_knife_s) then se_item.condition = (math.random(70,90)/100) news_manager.relocate_item(db.actor,"in",section,1) elseif (IsItem("multiuse",section)) then if (not uses) then local max_uses = ini_sys:r_float_ex(section,"max_uses") or 1 uses = math.random(1,max_uses) end alife_process_item(section, se_item.id, {uses = uses}) news_manager.relocate_item(db.actor,"in",section,uses) else news_manager.relocate_item(db.actor,"in",section,1) end end else printe("!ERROR reward_item | section [%s] doesn't exist", section) end end end function reward_random_item(actor,npc,p) if (#p > 0) then local section_d = p[math.random(#p)] reward_item(actor,npc,{section_d}) end end function reward_random_money(actor,npc,p) --local multi = game_difficulties.get_eco_factor("rewards") or 1 -->> --dialogs.relocate_money(db.actor,math.random(tonumber(p[1] or 500)*multi,tonumber(p[2] or 1000)*multi),"in") local multi = game_difficulties.get_eco_factor("rewards") or 1 local min_val = ( (tonumber(p[1]) or 500) * multi ) / 50 local max_val = ( (tonumber(p[2]) or (min_val + 1000)) * multi ) / 50 local money = math.random( math.ceil(min_val), math.ceil(max_val) ) * 50 dialogs.relocate_money( db.actor, money, "in" ) --printf("reward_random_money | min: %s - max: %s - multi:%s - total: %s", min_val*50 , max_val*50, multi, money) end function remove_special_task_squad(actor,npc,p) level.add_pp_effector("black.ppe", 1313, false) remove_squad(actor,npc,p) end function reset_task_target_anomaly(actor,npc,p) save_var(db.actor,"task_target_anomaly",nil) if _G.WARFARE then save_var(db.actor,"task_target_anomaly_analyzed","analyzed") -- xQd end end -- xQd function reset_warfare_escort_task() save_var(db.actor,"warfare_escort_task_smart",nil) save_var(db.actor,"task_target_anomaly_level",nil) save_var(db.actor,"task_target_anomaly_analyzed",nil) end -- xQd end -- setup for special escort to anomaly task function setup_task_target_anomaly(actor,npc,p)-- xQd, heavily modified for warfare tasks local targets = {} if _G.WARFARE then -- for k,v in pairs(db.anomaly_by_name) do -- table.insert(targets,k) -- end local targets, target_name if math.random(1,5) > 1 then -- 1/5 chance for the target anomaly zone to be in the same level targets = str_explode(simulation_objects.config:r_value(level.name(),"target_maps",0,""), ",") local remove_level = {l03u_agr_underground=true, l11_hospital=true, l10u_bunker=true, l12u_sarcofag=true, l12u_control_monolith=true, jupiter_underground=true, labx8=true, l08u_brainlab=true} -- these levels don't have anomaly zones or the anomaly zone is unreacheable for AI, so we remove them from targets local i=1 while i <= #targets do if remove_level[targets[i]] then table.remove(targets, i) else i = i + 1 end end if (#targets <= 0) then return end target_name = targets[math.random(#targets)] else target_name = level.name() end save_var(db.actor,"task_target_anomaly_level",target_name) -- xQd save_var(db.actor,"task_target_anomaly_analyzed","not_analyzed") -- xQd --save_var(db.actor,"task_target_anomaly",target_name) else for k,v in pairs(db.anomaly_by_name) do targets[#targets+1] = k end if (#targets <= 0) then return end local target_name = targets[math.random(#targets)] save_var(db.actor,"task_target_anomaly",target_name) end end function force_talk(actor,npc,p) local allow_break = p[1] and p[1] == "true" or false db.actor:run_talk_dialog(npc, allow_break) end function unlock_smart(actor,npc,p) local var = p[1] and p[1] ~= "nil" and load_var(db.actor,p[1]) local smart_id = var and var.smart_id local smart = smart_id and alife_object(smart_id) if (smart) then smart.locked = nil else printf("~ %s | failed to get smart (%s)", p[1], smart_id) end end -- Принудительно апдейтит логику у объектов, переданных параметром. Пока работает только с НПС function update_npc_logic(actor, object, p) --printf("UPDATE NPC LOGIC %s", device():time_global()) for k,v in pairs(p) do local npc = get_story_object(v) if npc ~= nil then xr_motivator.update_logic(npc) local planner = npc:motivation_action_manager() if planner and planner:initialized() then planner:update() planner:update() planner:update() end db.storage[npc:id()].state_mgr:update() db.storage[npc:id()].state_mgr:update() db.storage[npc:id()].state_mgr:update() db.storage[npc:id()].state_mgr:update() db.storage[npc:id()].state_mgr:update() db.storage[npc:id()].state_mgr:update() db.storage[npc:id()].state_mgr:update() end end end function update_obj_logic(actor, object, p) --printf("UPDATE OBJ LOGIC %s", device():time_global()) for k,v in pairs(p) do local obj = get_story_object(v) if obj ~= nil then local st = db.storage[obj:id()] xr_logic.try_switch_to_another_section(obj, st[st.active_scheme], actor) -- if st.active_scheme == "sr_cutscene" then -- st[st.active_scheme].cutscene_action -- end end end end local ui_active_slot = 0 function disable_ui(actor, npc, p) if db.actor:is_talking() then db.actor:stop_talk() end level.show_weapon(false) if not p or (p and p[1] ~= "true") then local slot = db.actor:active_slot() if(slot~=0) then ui_active_slot = slot db.actor:activate_slot(0) end end level.disable_input() show_indicators(false) --hide_hud_inventory() --hide_hud_pda() hide_hud_all() disable_actor_nightvision(nil,nil) disable_actor_torch(nil,nil) end function disable_ui_only(actor, npc) if db.actor:is_talking() then db.actor:stop_talk() end level.show_weapon(false) if not p or (p and p[1] ~= "true") then local slot = db.actor:active_slot() if(slot~=0) then ui_active_slot = slot db.actor:activate_slot(0) end end level.disable_input() show_indicators(false) --hide_hud_inventory() --hide_hud_pda() hide_hud_all() disable_actor_nightvision(nil,nil) end function disable_nv(actor, npc) if db.actor:is_talking() then db.actor:stop_talk() end level.show_weapon(false) if not p or (p and p[1] ~= "true") then local slot = db.actor:active_slot() if(slot~=0) then ui_active_slot = slot db.actor:activate_slot(0) end end disable_actor_nightvision(nil,nil) disable_actor_torch(nil,nil) end function disable_ui_lite_with_imput(actor, npc) if db.actor:is_talking() then db.actor:stop_talk() end level.show_weapon(false) if not p or (p and p[1] ~= "true") then local slot = db.actor:active_slot() if(slot~=0) then ui_active_slot = slot db.actor:activate_slot(0) end end level.disable_input() show_indicators(false) end function disable_ui_lite(actor, npc) if db.actor:is_talking() then db.actor:stop_talk() end level.show_weapon(false) if not p or (p and p[1] ~= "true") then local slot = db.actor:active_slot() if(slot~=0) then ui_active_slot = slot db.actor:activate_slot(0) end end show_indicators(false) end function disable_ui_inventory(actor, npc) if db.actor:is_talking() then db.actor:stop_talk() end -- level.show_weapon(false) if not p or (p and p[1] ~= "true") then local slot = db.actor:active_slot() if(slot~=0) then ui_active_slot = slot db.actor:activate_slot(0) end end --hide_hud_inventory() --hide_hud_pda() hide_hud_all() end function enable_ui(actor, npc, p) --db.actor:restore_weapon() if not p or (p and p[1] ~= "true") then if ui_active_slot ~= 0 and db.actor:item_in_slot(ui_active_slot) ~= nil then db.actor:activate_slot(ui_active_slot) end end ui_active_slot = 0 level.enable_input() level.show_weapon(true) show_indicators(true) enable_actor_nightvision(nil,nil) enable_actor_torch(nil,nil) end function enable_ui_lite_with_imput(actor, npc, p) --db.actor:restore_weapon() if not p or (p and p[1] ~= "true") then if ui_active_slot ~= 0 and db.actor:item_in_slot(ui_active_slot) ~= nil then db.actor:activate_slot(ui_active_slot) end end ui_active_slot = 0 level.enable_input() level.show_weapon(true) show_indicators(true) enable_actor_nightvision(nil,nil) enable_actor_torch(nil,nil) end function enable_ui_lite(actor, npc, p) --db.actor:restore_weapon() if not p or (p and p[1] ~= "true") then if ui_active_slot ~= 0 and db.actor:item_in_slot(ui_active_slot) ~= nil then db.actor:activate_slot(ui_active_slot) end end ui_active_slot = 0 level.enable_input() level.show_weapon(true) show_indicators(true) enable_actor_nightvision(nil,nil) enable_actor_torch(nil,nil) end function enable_nv_and_imput(actor, npc, p) --db.actor:restore_weapon() if not p or (p and p[1] ~= "true") then if ui_active_slot ~= 0 and db.actor:item_in_slot(ui_active_slot) ~= nil then db.actor:activate_slot(ui_active_slot) end end level.enable_input() enable_actor_nightvision(nil,nil) enable_actor_torch(nil,nil) end function enable_imput(actor, npc, p) --db.actor:restore_weapon() if not p or (p and p[1] ~= "true") then if ui_active_slot ~= 0 and db.actor:item_in_slot(ui_active_slot) ~= nil then db.actor:activate_slot(ui_active_slot) end end level.enable_input() end function enable_nv(actor, npc, p) --db.actor:restore_weapon() if not p or (p and p[1] ~= "true") then if ui_active_slot ~= 0 and db.actor:item_in_slot(ui_active_slot) ~= nil then db.actor:activate_slot(ui_active_slot) end end enable_actor_nightvision(nil,nil) enable_actor_torch(nil,nil) end local cam_effector_playing_object_id = nil function run_cam_effector(actor, npc, p) if p[1] then local loop, num = false, (1000 + math.random(100)) if p[2] and type(p[2]) == "number" and p[2] > 0 then num = p[2] end if p[3] and p[3] == "true" then loop = true end --level.add_pp_effector(p[1] .. ".ppe", num, loop) level.add_cam_effector("camera_effects\\" .. p[1] .. ".anm", num, loop, "xr_effects.cam_effector_callback") cam_effector_playing_object_id = npc:id() end end function stop_cam_effector(actor, npc, p) if p[1] and type(p[1]) == "number" and p[1] > 0 then level.remove_cam_effector(p[1]) end end function run_cam_effector_global(actor, npc, p) local num = 1000 + math.random(100) if p[2] and type(p[2]) == "number" and p[2] > 0 then num = p[2] end local fov = device().fov if p[3] ~= nil and type(p[3]) == "number" then fov = p[3] end level.add_cam_effector("camera_effects\\" .. p[1] .. ".anm", num, false, "xr_effects.cam_effector_callback", fov) cam_effector_playing_object_id = npc:id() end function cam_effector_callback() if cam_effector_playing_object_id == nil then printf("cam_eff:callback1!") return end local st = db.storage[cam_effector_playing_object_id] if st == nil or st.active_scheme == nil then printf("cam_eff:callback2!") return end if st[st.active_scheme].signals == nil then printf("cam_eff:callback3!") return end st[st.active_scheme].signals["cameff_end"] = true end function run_postprocess(actor, npc, p) if (p[1]) then if(ini_sys:section_exist(p[1])) then local num = 2000 + math.random(100) if(p[2] and type(p[2]) == "number" and p[2]>0) then num = p[2] end printf("adding complex effector [%s], id [%s], from [%s]", p[1], tostring(p[2]), tostring(npc:name())) level.add_complex_effector(p[1], num) else printf("Complex effector section is no set! [%s]", tostring(p[1])) end end end function stop_postprocess(actor, npc, p) if(p[1] and type(p[1]) == "number" and p[1]>0) then printf("removing complex effector id [%s] from [%s]", tostring(p[1]), tostring(npc:name())) level.remove_complex_effector(p[1]) end end function run_tutorial(actor, npc, p) --printf("run tutorial called") game.start_tutorial(p[1]) end --[[ function run_tutorial_if_newbie(actor, npc, p) if has_alife_info("esc_trader_newbie") then game.start_tutorial(p[1]) end end ]]-- function jup_b32_place_scanner(actor, npc) for i = 1, 5 do if xr_conditions.actor_in_zone(actor, npc, {"jup_b32_sr_scanner_place_"..i}) and not has_alife_info("jup_b32_scanner_"..i.."_placed") then db.actor:give_info_portion("jup_b32_scanner_"..i.."_placed") db.actor:give_info_portion("jup_b32_tutorial_done") remove_item(actor, npc, {"jup_b32_scanner_device"}) spawn_object(actor, nil, {"jup_b32_ph_scanner","jup_b32_scanner_place_"..i}) end end end function jup_b32_pda_check(actor, npc) end function pri_b306_generator_start(actor, npc) if xr_conditions.actor_in_zone(actor, npc, {"pri_b306_sr_generator"}) then give_info("pri_b306_lift_generator_used") end end function jup_b206_get_plant(actor, npc) if xr_conditions.actor_in_zone(actor, npc, {"jup_b206_sr_quest_line"}) then give_info("jup_b206_anomalous_grove_has_plant") give_actor(actor, npc, {"jup_b206_plant"}) destroy_object(actor, npc, {"story", "jup_b206_plant_ph"}) end end function pas_b400_switcher(actor, npc) if xr_conditions.actor_in_zone(actor, npc, {"pas_b400_sr_switcher"}) then give_info("pas_b400_switcher_use") end end function jup_b209_place_scanner(actor, npc) if xr_conditions.actor_in_zone(actor, npc, {"jup_b209_hypotheses"}) then scenario_autosave(db.actor, nil, {"st_save_jup_b209_placed_mutant_scanner"}) db.actor:give_info_portion("jup_b209_scanner_placed") remove_item(actor, npc, {"jup_b209_monster_scanner"}) spawn_object(actor, nil, {"jup_b209_ph_scanner","jup_b209_scanner_place_point"}) end end function jup_b9_heli_1_searching(actor, npc) if xr_conditions.actor_in_zone(actor, npc, {"jup_b9_heli_1"}) then db.actor:give_info_portion("jup_b9_heli_1_searching") end end function pri_a18_use_idol(actor, npc) if xr_conditions.actor_in_zone(actor, npc, {"pri_a18_use_idol_restrictor"}) then db.actor:give_info_portion("pri_a18_run_cam") end end function jup_b8_heli_4_searching(actor, npc) if xr_conditions.actor_in_zone(actor, npc, {"jup_b8_heli_4"}) then db.actor:give_info_portion("jup_b8_heli_4_searching") end end function jup_b10_ufo_searching(actor, npc) if xr_conditions.actor_in_zone(actor, npc, {"jup_b10_ufo_restrictor"}) then db.actor:give_info_portion("jup_b10_ufo_memory_started") give_actor(db.actor,nil,{"jup_b10_ufo_memory"}) end end function zat_b101_heli_5_searching(actor, npc) if xr_conditions.actor_in_zone(actor, npc, {"zat_b101_heli_5"}) then db.actor:give_info_portion("zat_b101_heli_5_searching") end end function zat_b28_heli_3_searching(actor, npc) if xr_conditions.actor_in_zone(actor, npc, {"zat_b28_heli_3"}) then db.actor:give_info_portion("zat_b28_heli_3_searching") end end function zat_b100_heli_2_searching(actor, npc) if xr_conditions.actor_in_zone(actor, npc, {"zat_b100_heli_2"}) then db.actor:give_info_portion("zat_b100_heli_2_searching") end end function teleport_actor(actor, npc, p) local point = patrol(p[1]) if not (point) then printf("xr_effects.teleport_actor no patrol path %s exists!",p[1]) return end local dir if p[2] ~= nil then local look = patrol(p[2]) dir = -look:point(0):sub(point:point(0)):getH() db.actor:set_actor_direction(dir) end for k,v in pairs(db.no_weap_zones) do if utils_obj.npc_in_zone(db.actor, k) then db.no_weap_zones[k] = true end end if npc and npc:name() ~= nil then printf("teleporting actor from [%s]", tostring(npc:name())) end db.actor:set_actor_position(point:point(0)) end local function reset_animation(npc) local state_mgr = db.storage[npc:id()].state_mgr if state_mgr == nil then return end -- local planner = npc:motivation_action_manager() state_mgr.animation:set_state(nil, true) state_mgr.animation:set_control() state_mgr.animstate:set_state(nil, true) state_mgr.animstate:set_control() state_mgr:set_state("idle", nil, nil, nil, {fast_set = true}) -- planner:update() -- planner:update() -- planner:update() state_mgr:update() state_mgr:update() state_mgr:update() state_mgr:update() state_mgr:update() state_mgr:update() state_mgr:update() npc:set_body_state(move.standing) npc:set_mental_state(anim.free) end function teleport_npc_lvid(actor,npc,p) local vid = tonumber(p[1]) if not (vid) then return end local position = level.vertex_position(vid) if (p[2]) then local obj = get_story_object(p[2]) if (obj) then obj:set_npc_position(position) end return end npc:set_npc_position(position) end function teleport_npc_pos(actor,npc,p) for i=1,3 do p[i] = string.gsub(p[i],"n","-") end local pos = vector():set(tonumber(p[1]),tonumber(p[2]),tonumber(p[3])) if not (pos) then return end if (p[4]) then local obj = get_story_object(p[4]) if (obj) then obj:set_npc_position(pos) end return end npc:set_npc_position(pos) end function teleport_squad_lvid(actor,npc,p) local vid = tonumber(p[1]) if not (vid) then return end local squad = p[2] and get_story_squad(p[2]) or get_object_squad(npc) if not (squad) then return end local position = level.vertex_position(vid) squad:set_squad_position(position) end function teleport_npc(actor, npc, p) if not (p[1]) then return end local position = patrol(p[1]):point(tonumber(p[2]) or 0) --reset_animation(npc) npc:set_npc_position(position) end function teleport_npc_by_story_id(actor, npc, p) local story_id = p[1] local patrol_point = p[2] local patrol_point_index = p[3] or 0 if story_id == nil or patrol_point == nil then printf("Wrong parameters in 'teleport_npc_by_story_id' function!!!") end local position = patrol(tostring(patrol_point)):point(patrol_point_index) local npc_id = get_story_object_id(story_id) if npc_id == nil then printf("There is no story object with id [%s]", story_id) end local cl_object = level.object_by_id(npc_id) if cl_object then reset_animation(cl_object) cl_object:set_npc_position(position) else alife_object(npc_id).position = position end end -- Teleports a squad, by story id, to another location -- param1 - squad story id -- param2 - path name -- param3 - optional path index function teleport_squad(actor, npc, p) local squad = p[1] and get_story_squad(p[1]) if not (squad) then printf("There is no squad with story id [%s]", p[1]) end local path = patrol(p[2]) if not (path) then printf("Wrong parameters in 'teleport_squad' function!!!") return end local idx = p[3] or 0 TeleportSquad(squad,path:point(idx),path:level_vertex_id(idx),path:game_vertex_id(idx)) --squad:set_squad_position(path:point(idx)) end function jup_teleport_actor(actor, npc) local point_in = patrol("jup_b16_teleport_in"):point(0) local point_out = patrol("jup_b16_teleport_out"):point(0) local actor_position = actor:position() local out_position = vector():set(actor_position.x - point_in.x + point_out.x, actor_position.y - point_in.y + point_out.y , actor_position.z - point_in.z + point_out.z) db.actor:set_actor_position(out_position) end ----------------------------------------------------------------------------- --[[ local drop_point, drop_object = 0, 0 local function drop_object_item(item) drop_object:drop_item_and_teleport(item, drop_point) end function drop_actor_inventory(actor, npc, p) if p[1] then drop_point = patrol(p[1]):point(0) drop_object = actor actor:inventory_for_each(drop_object_item) end end -- FIXME: drop_npc_inventory doesn't work function drop_npc_inventory(actor, npc, p) if p[1] then drop_point = patrol(p[1]):point(0) drop_object = npc npc:inventory_for_each(drop_object_item) end end function drop_npc_item(actor, npc, p) if p[1] then local item = npc:object(p[1]) if item then npc:drop_item(item) end end end function drop_npc_items(actor, npc, p) local item = 0 for i, v in pairs(p) do item = npc:object(v) if item then npc:drop_item(item) end end end ]]-- function give_items(actor, npc, p) local pos, lv_id, gv_id, npc_id = npc:position(), npc:level_vertex_id(), npc:game_vertex_id(), npc:id() for i, v in pairs(p) do alife_create_item(v, npc) --alife_create(v, pos, lv_id, gv_id, npc_id) end end function give_item(actor, npc, p) if p[2] ~= nil then npc_id = get_story_object_id(p[2]) else npc_id = npc:id() end local se_npc = alife_object(npc_id) if not (se_npc) then return end alife_create_item(p[1], se_npc) end function play_particle_on_path(actor, npc, p) local name = p[1] local path = p[2] local point_prob = p[3] if name == nil or path == nil then return end if point_prob == nil then point_prob = 100 end local path = patrol(path) local count = path:count() for a = 0,count-1,1 do local particle = particles_object(name) if math.random(100) <= point_prob then particle:play_at_pos(path:point(a)) end end end ----------------------------------------------------------------------------- --[[ send_tip(news_id:sender:sender_id) 1. news_id 2. sender* 3. sender_id* * - not necessary --]] function send_tip(actor, npc, p) news_manager.send_tip(actor, p[1], nil, p[2], nil, p[3]) end function send_tip_task(actor,npc,p) local tsk = p[1] and task_manager.get_task_manager().task_info[p[1]] if (tsk and p[2]) then news_manager.send_task(actor, p[2], tsk) end end --[[ Дать сталкеру небольшой пинок. Например чтоб скинуть его с возвышения. параметры: actor, npc, p[direction,bone,power,impulse,reverse=false] 1. direction - если строка, то считается, что это имя пути и в сторону первой точки производится толчек. Если же это число, то оно рассматривается как story_id персонажа от которого должен поступить хит. 2. bone - строка. Имя кости, по которой наносится удар. 3. power - сила удара 4. impulse - импульс 5. reverse (true/false) - изменение направления удара. по умолчанию false --]] function hit_npc(actor, npc, p) local h = hit() local rev = p[6] and p[6] == 'true' h.draftsman = npc h.type = hit.wound if p[1] ~= "self" then local hitter = get_story_object(p[1]) if not hitter then return end if rev then h.draftsman = hitter h.direction = hitter:position():sub(npc:position()) else h.direction = npc:position():sub(hitter:position()) end else if rev then h.draftsman = nil h.direction = npc:position():sub(patrol(p[2]):point(0)) else h.direction = patrol(p[2]):point(0):sub(npc:position()) end end h:bone(p[3]) h.power = p[4] h.impulse = p[5] --printf("HIT EFFECT: (%s, %s,%d,%d) health(%s)", npc:name(), p[2], h.power, h.impulse, npc.health) npc:hit(h) end --[[ Дать обьекту, заданному story_id, хит. параметры: actor, npc, p[sid,bone,power,impulse,hit_src=npc:position()] 1. sid - story_id обьекта, по которому наносится хит. 2. bone - строка. Имя кости, по которой наносится удар. 3. power - сила удара 4. impulse - импульс 5. hit_src - если число, то рассматривается как story_id обьекта, со стороны которого наносится хит (он же является и инициатором хита), иначе это точка (waypoint), из которой по объекту наносится хит. Если не задано, то берется позиция обьекта, из которого была вызвана данная функция. --]] function hit_obj(actor, npc, p) local h = hit() local obj = get_story_object(p[1]) local sid = nil if not obj then -- printf("HIT_OBJ [%s]. Target object does not exist", npc:name()) return end h:bone(p[2]) h.power = p[3] h.impulse = p[4] if p[5] then sid = get_story_object(sid) if sid then h.direction = vec_sub(sid:position(), obj:position()) end if not sid then h.direction = vec_sub(patrol(p[5]):point(0), obj:position()) end else h.direction = vec_sub(npc:position(), obj:position()) end h.draftsman = sid or npc h.type = hit.wound obj:hit(h) end function hit_obj_chemical(actor, npc, p) local h = hit() local obj = get_story_object(p[1]) local sid = nil if not obj then -- printf("HIT_OBJ [%s]. Target object does not exist", npc:name()) return end h:bone(p[2]) h.power = p[3] h.impulse = p[4] if p[5] then sid = get_story_object(sid) if sid then h.direction = vec_sub(sid:position(), obj:position()) end if not sid then h.direction = vec_sub(patrol(p[5]):point(0), obj:position()) end else h.direction = vec_sub(npc:position(), obj:position()) end h.draftsman = sid or npc h.type = hit.chemical_burn obj:hit(h) end function hit_obj_fire_wound(actor, npc, p) local h = hit() local obj = get_story_object(p[1]) local sid = nil if not obj then -- printf("HIT_OBJ [%s]. Target object does not exist", npc:name()) return end h:bone(p[2]) h.power = p[3] h.impulse = p[4] if p[5] then sid = get_story_object(sid) if sid then h.direction = vec_sub(sid:position(), obj:position()) end if not sid then h.direction = vec_sub(patrol(p[5]):point(0), obj:position()) end else h.direction = vec_sub(npc:position(), obj:position()) end h.draftsman = sid or npc h.type = hit.fire_wound obj:hit(h) end --[[ Дать сталкеру небольшой пинок после смерти. Аналогично предыдущему, только направление хита теперь вычисляется через убийцу. Поэтому параметра direction нет. параметры: actor, npc, p[bone,power,impulse] FIXME: killer:position() isn't working <-(Because you are fucking stupid) --]] function hit_by_killer(actor, npc, p) if not npc then return end local t = db.storage[npc:id()].death if not (t) then return false end if (t.killer == nil or t.killer == -1) then return false end local killer = db.storage[t.killer].object or level.object_by_id(t.killer) if not (killer) then return false end local p1, p2 p1 = npc:position() p2 = killer:position() local h = hit() h.draftsman = npc h.type = hit.wound h.direction = vector():set(p1):sub(p2) h.bone = p[1] h.power = p[2] h.impulse = p[3] npc:hit(h) end function hit_npc_from_actor(actor, npc, p) local h = hit() local sid = nil h.draftsman = actor h.type = hit.wound if p and p[1] then sid = get_story_object(p[1]) if sid then h.direction = actor:position():sub(sid:position()) end if not sid then h.direction = actor:position():sub(npc:position()) end else h.direction = actor:position():sub(npc:position()) sid = npc end h:bone("bip01_spine") h.power = 0.001 h.impulse = 0.001 sid:hit(h) end --[[ -- Хитует нпс от нпс, если задан один параметр (стори айди), то нпс с таким стори айди хитнет нпс у которого вызвали эту функцию. -- если задано 2 стори айди , то нпс с 1-ым стори айди хитнет нпс со 2-ым стори айди. function hit_npc_from_npc(actor, npc, p) if p == nil then printf("Invalid parameter in function 'hit_npc_from_npc'!!!!") end local h = hit() local hitted_npc = npc h.draftsman = get_story_object(p[1]) if p[2] ~= nil then hitted_npc = get_story_object(p[2]) end h.type = hit.wound h.direction = h.draftsman:position():sub(hitted_npc:position()) h:bone("bip01_spine") h.power = 0.03 h.impulse = 0.03 hitted_npc:hit(h) end function hit_actor(actor, npc, p) local h = hit() h.direction = VEC_ZERO h.draftsman = actor h.type = hit.shock h:bone("bip01_spine") h.power = (p and p[1] and tonumber(p[1])) or 0.001 h.impulse = 0.001 actor:hit(h) end ]]-- function restore_health_portion(actor, npc) local health = npc.health local diff = 1 - health if diff > 0 then npc.health = health + math.random(diff * 0.5, diff * 0.95) end end function restore_health(actor, npc) --printf("HEALTH RESTORE") npc.health = 1 end function make_enemy(actor, npc, p) --[[ if p == nil then printf("Invalid parameter in function 'hit_npc_from_npc'!!!!") end local h = hit() local hitted_npc = npc h.draftsman = get_story_object(p[1]) if p[2] ~= nil then hitted_npc = get_story_object(p[2]) end h.type = hit.wound h.direction = h.draftsman:position():sub(hitted_npc:position()) h:bone("bip01_spine") h.power = 0.03 h.impulse = 0.03 hitted_npc:hit(h) --]] local npc1 = get_story_object(p[1]) if not (npc1) then return end local npc2 = get_story_object(p[2]) if not (npc2) then return end npc1:set_relation(game_object.enemy,npc2) npc2:set_relation(game_object.enemy,npc1) end function sniper_fire_mode(actor, npc, p) if p[1] == "true" then --printf("SNIPER FIRE MODE ON") npc:sniper_fire_mode(true) else --printf("SNIPER FIRE MODE OFF") npc:sniper_fire_mode(false) end end function kill_npc(actor, npc, p) if p and p[1] then npc = get_story_object(p[1]) end if npc ~= nil and npc:alive() then npc:kill(npc) end end function remove_npc(actor, npc, p) if p and p[1] then npc_id = get_story_object_id(p[1]) end if npc_id ~= nil then local se_obj = alife_object(npc_id) if (se_obj) then safe_release_manager.release(se_obj) --alife_release(se_obj) end end end -- прибавить к указанному счётчику актёра 1 function inc_counter(actor, npc, p) if p and p[1] then local inc_value = p[2] or 1 local new_value = load_var(actor, p[1], 0) + inc_value if npc and npc:name() then printf("inc_counter '%s' to value [%s], by [%s]", p[1], tostring(new_value), tostring(npc:name())) end save_var(actor, p[1], new_value) end end function dec_counter(actor, npc, p) if p and p[1] then local dec_value = p[2] or 1 local new_value = load_var(actor, p[1], 0) - dec_value if new_value < 0 then new_value = 0 end save_var(actor, p[1], new_value) if npc and npc:name() then printf( "dec_counter [%s] value [%s] by [%s]", p[1], load_var(actor, p[1], 0), tostring(npc:name())) end end end function set_counter(actor, npc, p) if p and p[1] then local count = p[2] or 0 -- printf( "set_counter '%s' %s", p[1], count) save_var(actor, p[1], count) -- printf("counter [%s] value [%s]", p[1], load_var(actor, p[1], 0)) end end ------------------------------------------------------------------------------------------------------------------------ -- постпроцесс и влияние удара в морду function actor_punch(npc) if db.actor:position():distance_to_sqr(npc:position()) > 4 then return end set_inactivate_input_time(30) level.add_cam_effector("camera_effects\\fusker.anm", 999, false, "") local active_slot = db.actor:active_slot() if active_slot ~= 2 and active_slot ~= 3 then return end local active_item = db.actor:active_item() if active_item and string.find(active_item:section(),'wpn_') then db.actor:drop_item(active_item) end end -- забывание обиды function clearAbuse(npc) printf("CLEAR_ABUSE") xr_abuse.clear_abuse(npc) end function turn_off_underpass_lamps(actor, npc) local lamps_table = { ["pas_b400_lamp_start_flash"] = true, ["pas_b400_lamp_start_red"] = true, ["pas_b400_lamp_elevator_green"] = true, ["pas_b400_lamp_elevator_flash"] = true, ["pas_b400_lamp_elevator_green_1"] = true, ["pas_b400_lamp_elevator_flash_1"] = true, ["pas_b400_lamp_track_green"] = true, ["pas_b400_lamp_track_flash"] = true, ["pas_b400_lamp_downstairs_green"] = true, ["pas_b400_lamp_downstairs_flash"] = true, ["pas_b400_lamp_tunnel_green"] = true, ["pas_b400_lamp_tunnel_flash"] = true, ["pas_b400_lamp_tunnel_green_1"] = true, ["pas_b400_lamp_tunnel_flash_1"] = true, ["pas_b400_lamp_control_down_green"] = true, ["pas_b400_lamp_control_down_flash"] = true, ["pas_b400_lamp_control_up_green"] = true, ["pas_b400_lamp_control_up_flash"] = true, ["pas_b400_lamp_hall_green"] = true, ["pas_b400_lamp_hall_flash"] = true, ["pas_b400_lamp_way_green"] = true, ["pas_b400_lamp_way_flash"] = true, } for k,v in pairs(lamps_table) do local obj = get_story_object(k) if obj then obj:get_hanging_lamp():turn_off() else printf("function 'turn_off_underpass_lamps' lamp [%s] does not exist", tostring(k)) --printf("function 'turn_off_underpass_lamps' lamp [%s] does not exist", tostring(k)) end end end ---Выключение динамической лампочки (hanging_lamp) function turn_off(actor, npc, p) for k,v in pairs(p) do local obj = get_story_object(v) if not obj then printf("TURN_OFF. Target object with story_id [%s] does not exist", v) return end obj:get_hanging_lamp():turn_off() --printf("TURN_OFF. Target object with story_id [%s] turned off.", v) end end function turn_off_object(actor, npc) npc:get_hanging_lamp():turn_off() end ---Включение динамической лампочки (hanging_lamp) function turn_on(actor, npc, p) for k,v in pairs(p) do local obj = get_story_object(v) if not obj then printf("TURN_ON [%s]. Target object does not exist", npc:name()) return end obj:get_hanging_lamp():turn_on() end end ---Включение и запуск динамической лампочки (hanging_lamp) function turn_on_and_force(actor, npc, p) local obj = get_story_object(p[1]) if not obj then printf("TURN_ON_AND_FORCE. Target object does not exist") return end if p[2] == nil then p[2] = 55 end if p[3] == nil then p[3] = 14000 end obj:set_const_force(VEC_Y, p[2], p[3]) obj:start_particles("weapons\\light_signal", "link") obj:get_hanging_lamp():turn_on() end ---Выключение динамической лампочки и партиклов (hanging_lamp) function turn_off_and_force(actor, npc, p) local obj = get_story_object(p[1]) if not obj then printf("TURN_OFF [%s]. Target object does not exist", npc:name()) return end obj:stop_particles("weapons\\light_signal", "link") obj:get_hanging_lamp():turn_off() end function turn_on_object(actor, npc) npc:get_hanging_lamp():turn_on() end function turn_off_object(actor, npc) npc:get_hanging_lamp():turn_off() end -- Вызов этой функции отключит обработчик [combat] боя для персонажа. -- Используется в случаях, когда все необходимые действия, такие как переключение на другую секцию, -- уже выполнены, и повторно выполнять их во время боя нельзя (а условия секции [combat] проверяются на каждом -- апдейте, когда персонаж в бою, если, конечно, не отключены вызовом этой функции). function disable_combat_handler(actor, npc) if db.storage[npc:id()].combat then db.storage[npc:id()].combat.enabled = false end if db.storage[npc:id()].mob_combat then db.storage[npc:id()].mob_combat.enabled = false end end -- Вызов этой функции отключит обработчик [combat_ignore] перехвата боя для персонажа. function disable_combat_ignore_handler(actor, npc) if db.storage[npc:id()].combat_ignore then db.storage[npc:id()].combat_ignore.enabled = false end end ------------------------------------------------------------------------------------- -- Функции для работы с вертолётами ------------------------------------------------------------------------------------- --[[ function heli_set_enemy_actor(actor, npc) local st = db.storage[npc:id()] if not st.combat.enemy_id and actor:alive() then st.combat.enemy_id = actor:id() heli_snd.play_snd( st, heli_snd.snd_see_enemy, 1 ) end end function heli_set_enemy(actor, npc, p) local st = db.storage[npc:id()] local obj = get_story_object( p[1] ) if not st.combat.enemy_id and obj:alive() then st.combat.enemy_id = obj:id() heli_snd.play_snd( st, heli_snd.snd_see_enemy, 1 ) end end function heli_clear_enemy(actor, npc) db.storage[npc:id()].combat:forget_enemy() end ]]-- function heli_start_flame(actor, npc) bind_heli.heli_start_flame( npc ) end function heli_die(actor, npc) bind_heli.heli_die( npc ) end --'----------------------------------------------------------------------------------- --' Функции для работы с погодными эффектами --'----------------------------------------------------------------------------------- -- Принудительная установка погодных условий -- =set_weather(<секция погоды>:true) - установка погоды сразу, false - через некоторое время -- Будет использоваться на старте игры Зов Припяти и в сцене jup_b15 - утро после пьянки с Зулусом function set_weather(actor, npc, p) if(p[1]) then if(p[2]=="true") then level.set_weather(p[1],true) else level.set_weather(p[1],false) end end end --[[ function update_weather(actor, npc, p) if p and p[1] then if p[1] == "true" then level_weathers.get_weather_manager():select_weather(true) elseif p[1] == "false" then level_weathers.get_weather_manager():select_weather(false) end end end function start_small_reject(actor, npc) level.set_weather_fx("fx_surge_day_3") level.add_pp_effector("vibros_p.ppe", 1974, false) this.aes_earthshake(npc) end function start_full_reject(actor, npc) level.set_weather_fx("fx_surge_day_3") level.remove_pp_effector(1974) level.remove_cam_effector(1975) level.add_cam_effector("camera_effects\\earthquake.anm", 1975, true, "") end function stop_full_reject(actor, npc) level.remove_pp_effector(1974) level.remove_cam_effector(1975) end function run_weather_pp(actor,npc, p) local weather_fx = p[1] if weather_fx == nil then weather_fx = "fx_surge_day_3" end level.set_weather_fx(weather_fx) end ]]-- function game_disconnect(actor, npc) local c = get_console() exec_console_cmd("disconnect") -- c:execute_deferred("main_menu off") -- c:execute_deferred("hide") end function game_credits(actor, npc) db.gameover_credits_started = true game.start_tutorial("credits_seq") end function game_over(actor, npc) if db.gameover_credits_started ~= true then return end printf("main_menu on console command is executed") exec_console_cmd("main_menu on") end function after_credits(actor, npc) exec_console_cmd("main_menu on") end function before_credits(actor, npc) exec_console_cmd("main_menu off") end function on_tutor_gameover_stop() printf("main_menu on console command is executed") exec_console_cmd("main_menu on") end function on_tutor_gameover_quickload() exec_console_cmd("load_last_save") end -- для смены работы function get_stalker_for_new_job(actor, npc, p) xr_gulag.find_stalker_for_job(npc,p[1]) end function switch_to_desired_job(actor, npc, p) xr_gulag.switch_to_desired_job(npc) end --[[ function death_hit(actor, npc, p) local draftsman = get_story_object (p[1]) local hitted_obj = (p[2] ~= nil and get_story_object (p[2])) or npc if draftsman == nil or hitted_obj == nil then return end local h = hit() h.power = 1000 h.direction = hitted_obj:direction() h.draftsman = draftsman h.impulse = 1 h.type = hit.wound hitted_obj:hit(h) end ]]-- --'----------------------------------------------------------------------------------- --' Функции для работы с подспауном --'----------------------------------------------------------------------------------- function spawn_object(actor, obj, p) --' p[1] - секция кого спаунить --' p[2] - имя патрульного пути где спа унить. local spawn_sect = p[1] if spawn_sect == nil then printf("Wrong spawn section for 'spawn_object' function %s. For object %s", tostring(spawn_sect), obj:name()) end local path_name = p[2] if path_name == nil then printf("Wrong path_name for 'spawn_object' function %s. For object %s", tostring(path_name), obj:name()) end if not level.patrol_path_exists(path_name) then printf("Path %s doesnt exist. Function 'spawn_object' for object %s ", tostring(path_name), obj:name()) end local ptr = patrol(path_name) local index = p[3] or 0 local yaw = p[4] or 0 --' printf("Spawning %s at %s, %s", tostring(p[1]), tostring(p[2]), tostring(p[3])) local se_obj = alife_create(spawn_sect,ptr:point(index),ptr:level_vertex_id(0),ptr:game_vertex_id(0)) if (se_obj) then if IsStalker( nil, se_obj:clsid()) then se_obj:o_torso().yaw = yaw * math.pi / 180 elseif se_obj:clsid() == clsid.script_phys then se_obj:set_yaw(yaw * math.pi / 180) end end end local jup_b219_position local jup_b219_lvid local jup_b219_gvid function jup_b219_save_pos() local obj = get_story_object("jup_b219_gate_id") if obj and obj:position() then jup_b219_position = obj:position() jup_b219_lvid = obj:level_vertex_id() jup_b219_gvid = obj:game_vertex_id() else return end alife_release_id(obj:id()) end function jup_b219_restore_gate() local yaw = 0 local spawn_sect = "jup_b219_gate" if jup_b219_position then local se_obj = alife_create(spawn_sect,vector():set(jup_b219_position),jup_b219_lvid,jup_b219_gvid) if (se_obj) then se_obj:set_yaw(yaw * math.pi / 180) end end end function spawn_corpse(actor, obj, p) --' p[1] - секция кого спаунить --' p[2] - имя патрульного пути где спаунить. local spawn_sect = p[1] if spawn_sect == nil then printf("Wrong spawn section for 'spawn_corpse' function %s. For object %s", tostring(spawn_sect), obj:name()) end local path_name = p[2] if path_name == nil then printf("Wrong path_name for 'spawn_corpse' function %s. For object %s", tostring(path_name), obj:name()) end if not level.patrol_path_exists(path_name) then printf("Path %s doesnt exist. Function 'spawn_corpse' for object %s ", tostring(path_name), obj:name()) end local ptr = patrol(path_name) local index = p[3] or 0 local se_obj = alife_create(spawn_sect,ptr:point(index),ptr:level_vertex_id(0),ptr:game_vertex_id(0)) if (se_obj) then se_obj:kill() end end function spawn_object_in(actor, obj, p) --' p[1] - секция кого спаунить --' p[2] - стори айди обьекта в который спавнить local spawn_sect = p[1] if spawn_sect == nil then printf("Wrong spawn section for 'spawn_object' function %s. For object %s", tostring(spawn_sect), obj:name()) end if p[2] == nil then printf("Wrong target_name for 'spawn_object_in' function %s. For object %s", tostring(target_name), obj:name()) end -- local box = alife_object(target_name) -- if(box==nil) then printf("xr_effects.spawn_object_in trying to find object %s", tostring(p[2])) local target_obj_id = get_story_object_id(p[2]) if target_obj_id ~= nil then box = alife_object(target_obj_id) if box == nil then printf("xr_effects.spawn_object_in There is no such object %s", p[2]) end alife_create(spawn_sect, box.position, box.m_level_vertex_id, box.m_game_vertex_id, target_obj_id) else printf("xr_effects.spawn_object_in object is nil %s", tostring(p[2])) end end function spawn_npc_in_zone(actor, obj, p) --' p[1] - секция кого спаунить --' p[2] - имя зоны в которой спаунить. local spawn_sect = p[1] if spawn_sect == nil then printf("Wrong spawn section for 'spawn_object' function %s. For object %s", tostring(spawn_sect), obj:name()) end local zone_name = p[2] if zone_name == nil then printf("Wrong zone_name for 'spawn_object' function %s. For object %s", tostring(zone_name), obj:name()) end if db.zone_by_name[zone_name] == nil then printf("Zone %s doesnt exist. Function 'spawn_object' for object %s ", tostring(zone_name), obj:name()) end local zone = db.zone_by_name[zone_name] -- printf("spawn_npc_in_zone: spawning %s at zone %s, squad %s", tostring(p[1]), tostring(p[2]), tostring(p[3])) local spawned_obj = alife_create( spawn_sect, zone:position(), zone:level_vertex_id(), zone:game_vertex_id()) spawned_obj.sim_forced_online = true spawned_obj.squad = 1 or p[3] db.script_ids[spawned_obj.id] = zone_name end function destroy_object(actor, obj, p) local sobj if (p == nil or p[1] == nil) then sobj = alife_object(obj:id()) elseif (p[1] == "story" and p[2] ~= nil) then local id = get_story_object_id(p[2]) if not (id) then printf("destroy_object %s story id doesn't exist!",p[2]) end sobj = id and alife_object(id) end if not (sobj) then return end -- TODO: check this local cls = sobj:clsid() if (cls == clsid.online_offline_group_s or IsStalker(nil,cls) or IsMonster(nil,cls)) then safe_release_manager.release(sobj) else alife_release(sobj) end end function give_actor(actor, npc, p) for k,v in pairs(p) do alife_create(v, db.actor:position(), db.actor:level_vertex_id(), db.actor:game_vertex_id(), AC_ID) news_manager.relocate_item(db.actor, "in", v) end end function activate_weapon_slot(actor, npc, p) db.actor:activate_slot(p[1]) end function anim_obj_forward(actor, npc, p) for k,v in pairs(p) do if v ~= nil then db.anim_obj_by_name[v]:anim_forward() end end end function anim_obj_backward(actor, npc, p) if p[1] ~= nil then db.anim_obj_by_name[p[1]]:anim_backward() end end function anim_obj_stop(actor, npc, p) if p[1] ~= nil then db.anim_obj_by_name[p[1]]:anim_stop() end end -- Функции для работы с огненными зонами. --[[ function turn_on_fire_zone(actor, npc, p) bind_campfire.fire_zones_table[ p[1] ]:turn_on() end function turn_off_fire_zone(actor, npc, p) bind_campfire.fire_zones_table[ p[1] ]:turn_off() end ]]-- --'----------------------------------------------------------------------------------- --' Функции для отыгрывания звука --'----------------------------------------------------------------------------------- function play_sound_on_actor(actor,obj,p) local snd = sound_object(p[1]) if (snd) then --snd:play_at_pos(db.actor,db.actor:position(),0,sound_object.s3d) snd:play(db.actor, 0, sound_object.s2d) end end function play_sound(actor, obj, p) local theme = p[1] local faction = p[2] local point if (p[3]) then local smart = SIMBOARD.smarts_by_names[p[3]] if (smart) then point = smart.id else point = p[3] end end if obj and IsStalker(obj) then if not obj:alive() then printf("Stalker [%s][%s] is dead, but you wants to say something for you: [%s]!", tostring(obj:id()), tostring(obj:name()), p[1]) end end xr_sound.set_sound_play(obj:id(), theme, faction, point) end function play_sound_by_story(actor, obj, p) local story_obj = get_story_object_id(p[1]) local theme = p[2] local faction = p[3] local point = SIMBOARD.smarts_by_names[p[4]] if point ~= nil then point = point.id elseif p[4]~=nil then point = p[4] end xr_sound.set_sound_play(story_obj, theme, faction, point) end function stop_sound(actor, npc) xr_sound.stop_sounds_by_id(npc:id()) end function play_sound_looped(actor, obj, p) local theme = p[1] xr_sound.play_sound_looped(obj:id(), theme) end function stop_sound_looped(actor, obj) xr_sound.stop_sound_looped(obj:id()) end function barrel_explode (actor , npc , p) local expl_obj = get_story_object (p[1]) if expl_obj ~= nil then expl_obj:explode(0) end end --com function play_inv_repair_kit_use_fast_2p8() xr_sound.set_sound_play(AC_ID,"inv_repair_kit_use_fast_2p8") end function play_inv_repair_kit_use_fast() xr_sound.set_sound_play(AC_ID,"inv_repair_kit_use_fast") end function play_inv_repair_kit_with_brushes() xr_sound.set_sound_play(AC_ID,"inv_repair_kit_with_brushes") end function play_inv_repair_sewing_kit() xr_sound.set_sound_play(AC_ID,"inv_repair_sewing_kit") end function play_inv_repair_sewing_kit_fast() xr_sound.set_sound_play(AC_ID,"inv_repair_sewing_kit_fast") end function play_inv_repair_spray_oil() xr_sound.set_sound_play(AC_ID,"inv_repair_spray_oil") end function play_inv_repair_brushes() xr_sound.set_sound_play(AC_ID,"inv_repair_brushes") end function play_inv_repair_kit() xr_sound.set_sound_play(AC_ID,"inv_repair_kit") end function play_inv_drink_flask_2() xr_sound.set_sound_play(AC_ID,"inv_drink_flask_2") end function play_inv_cooking() xr_sound.set_sound_play(AC_ID,"inv_cooking") end function play_inv_cooking_cooker() xr_sound.set_sound_play(AC_ID,"inv_cooking_cooker") end function play_inv_cooking_stove() xr_sound.set_sound_play(AC_ID,"inv_cooking_stove") end function play_inv_aam_open() xr_sound.set_sound_play(AC_ID,"inv_aam_open") end function play_inv_aam_close() xr_sound.set_sound_play(AC_ID,"inv_aam_close") end function play_inv_aac_open() xr_sound.set_sound_play(AC_ID,"inv_aac_open") end function play_inv_aac_close() xr_sound.set_sound_play(AC_ID,"inv_aac_close") end function play_inv_iam_open() xr_sound.set_sound_play(AC_ID,"inv_iam_open") end function play_inv_iam_close() xr_sound.set_sound_play(AC_ID,"inv_iam_close") end function play_inv_lead_open() xr_sound.set_sound_play(AC_ID,"inv_lead_open") end function play_inv_lead_close() xr_sound.set_sound_play(AC_ID,"inv_lead_close") end function play_inv_batteries_switch() xr_sound.set_sound_play(AC_ID,"inv_batt") end function play_inv_mask_clean() xr_sound.set_sound_play(AC_ID,"inv_mask_clean") end function play_inv_drop() xr_sound.set_sound_play(AC_ID,"inv_drop") end function play_inv_drop() xr_sound.set_sound_play(AC_ID,"inv_drop") end function play_inv_empty() xr_sound.set_sound_play(AC_ID,"inv_empty") end function play_inv_smoke_bag_open() xr_sound.set_sound_play(AC_ID,"inv_smoke_bag_open") end function play_inv_eat_can_imm() xr_sound.set_sound_play(AC_ID,"inv_eat_can_imm") end function play_inv_open() xr_sound.set_sound_play(AC_ID,"inv_open") end function play_inv_briefcase_light_open() xr_sound.set_sound_play(AC_ID,"inv_briefcase_light_open") end function play_inv_disassemble_metal_fast() xr_sound.set_sound_play(AC_ID,"inv_disassemble_metal_fast") end function play_inv_disassemble_cloth_fast() xr_sound.set_sound_play(AC_ID,"inv_disassemble_cloth_fast") end function play_inv_tear_patch() xr_sound.set_sound_play(AC_ID,"inv_tear_patch") end --'----------------------------------------------------------------------------------- --' Alife support --'----------------------------------------------------------------------------------- --[[ function start_sim(actor, obj) SIMBOARD:start_sim() end function stop_sim(actor, obj) SIMBOARD:stop_sim() end function update_faction_brain(actor, obj, p) if p[1] == nil then printf("Wrong parameters update_faction_brain") end local board = SIMBOARD local player = board.players[ p[1] ] if player == nil then printf("Can't find player %s", tostring(p[1])) end player:faction_brain_update() end ]]-- function create_squad(actor, obj, p) local squad_id = p[1] if squad_id == nil then printf("Wrong squad identificator [NIL] in create_squad function") return end local smart_name = p[2] if smart_name == nil then printf("Wrong smart name [NIL] in create_squad function") return end if not ini_sys:section_exist(squad_id) then printf("Wrong squad identificator [%s]. Squad descr doesnt exist.", tostring(squad_id)) end local board = SIMBOARD local smart = board.smarts_by_names[smart_name] if smart == nil then printf("Wrong smart_name [%s] for [%s] faction in create_squad function", tostring(smart_name), tostring(player_name)) end --printf("Create squad %s BEFORE",squad_id) local squad = board:create_squad(smart, squad_id) if not (squad) then return end --printf("Create squad %s AFTER",squad_id) --board:enter_smart(squad, smart.id) local sim = alife() for k in squad:squad_members() do local se_obj = k.object or k.id and sim:object(k.id) if (se_obj) then board:setup_squad_and_group(se_obj) end end --squad:update() end function create_squad_member(actor, obj, p) local squad_member_sect = p[1] local story_id = p[2] local position = nil local level_vertex_id = nil local game_vertex_id = nil if story_id == nil then printf("Wrong squad identificator [NIL] in 'create_squad_member' function") end local board = SIMBOARD local squad = get_story_squad(story_id) if not (squad) then return end local squad_smart = squad.smart_id and board.smarts[squad.smart_id].smrt if not (squad_smart) then return end if p[3] ~= nil then local spawn_point if p[3] == "simulation_point" then spawn_point = ini_sys:r_string_ex(squad:section_name(),"spawn_point") if spawn_point == "" or spawn_point == nil then spawn_point = xr_logic.parse_condlist(obj, "spawn_point", "spawn_point", squad_smart.spawn_point) else spawn_point = xr_logic.parse_condlist(obj, "spawn_point", "spawn_point", spawn_point) end spawn_point = xr_logic.pick_section_from_condlist(db.actor, obj, spawn_point) else spawn_point = p[3] end position = patrol(spawn_point):point(0) level_vertex_id = patrol(spawn_point):level_vertex_id(0) game_vertex_id = patrol(spawn_point):game_vertex_id(0) else local commander = alife_object(squad:commander_id()) position = commander.position level_vertex_id = commander.m_level_vertex_id game_vertex_id = commander.m_game_vertex_id end local new_member_id = squad:add_squad_member(squad_member_sect, position, level_vertex_id, game_vertex_id) local se_obj = new_member_id and alife_object(new_member_id) if (se_obj) then squad_smart:register_npc(se_obj) board:setup_squad_and_group(se_obj) end --board:setup_squad_and_group(alife_object(new_member_id)) --squad_smart:refresh() squad:update() end function remove_squad(actor, obj, p) local story_id = p[1] if story_id == nil then printf("Wrong squad identificator [NIL] in remove_squad function") end local squad = get_story_squad(story_id) if squad == nil then assert("Wrong squad identificator [%s]. squad doesnt exist", tostring(story_id)) return end SIMBOARD:remove_squad(squad) end function kill_squad(actor, obj, p) local story_id = p[1] if story_id == nil then printf("Wrong squad identificator [NIL] in kill_squad function") end local squad = get_story_squad(story_id) if squad == nil then return end local squad_npcs = {} for k in squad:squad_members() do squad_npcs[k.id] = true end for k,v in pairs(squad_npcs) do local cl_obj = db.storage[k] and db.storage[k].object if cl_obj == nil then alife_object(tonumber(k)):kill() else cl_obj:kill(cl_obj) end end end function heal_squad(actor, obj, p) local story_id = p[1] local health_mod = 1 if p[2] and p[2] ~= nil then health_mod = math.ceil(p[2]/100) end if story_id == nil then printf("Wrong squad identificator [NIL] in heal_squad function") end local squad = get_story_squad(story_id) if squad == nil then return end for k in squad:squad_members() do local cl_obj = db.storage[k.id] and db.storage[k.id].object if cl_obj ~= nil then cl_obj:change_health(health_mod) end end end --[[ function update_squad(actor, obj, p) local squad_id = p[1] if squad_id == nil then printf("Wrong squad identificator [NIL] in remove_squad function") end local board = SIMBOARD local squad = board.squads[squad_id] if squad == nil then assert("Wrong squad identificator [%s]. squad doesnt exist", tostring(squad_id)) return end squad:update() end ]]-- -- this deletes squads from a smart function clear_smart_terrain(actor, obj, p) local smart_name = p[1] if smart_name == nil then printf("Wrong squad identificator [NIL] in clear_smart_terrain function") end local board = SIMBOARD local smart = board.smarts_by_names[smart_name] local smart_id = smart.id for k,v in pairs(board.smarts[smart_id].squads) do local squad = alife_object(k) if (squad) then if p[2] and p[2] == "true" then board:remove_squad(squad) else if not get_object_story_id(squad.id) then board:remove_squad(squad) end end end end end -- This forces squads to leave a smart function flush_smart_terrain(actor,obj,p) local smart_name = p[1] if smart_name == nil then printf("Wrong squad identificator [NIL] in clear_smart_terrain function") return end local function unregister(squad) squad.assigned_target_id = nil squad.current_target_id = nil squad.current_action = nil squad.was_forced_offline = true SIMBOARD:assign_squad_to_smart(squad, nil) for k in squad:squad_members() do local se_obj = alife_object(k.id) if (se_obj) then local smart_id = se_obj.m_smart_terrain_id if (smart_id and smart_id ~= 65535) then local smart = alife_object(smart_id) if (smart) then smart:unregister_npc(se_obj) end end end end end local smart = SIMBOARD.smarts_by_names[smart_name] local smart_id = smart.id for k,v in pairs(SIMBOARD.smarts[smart_id].squads) do local squad = alife_object(k) if (squad) then if p[2] and p[2] == "true" then unregister(squad) else if not get_object_story_id(k) then unregister(squad) end end end end end --[[ function set_actor_faction(actor, obj, p) if p[1] == nil then printf("Wrong parameters") end SIMBOARD:set_actor_community(p[1]) end ]]-- --'----------------------------------------------------------------------------------- --' Quest support --'----------------------------------------------------------------------------------- -- TODO: add param 2 for story_id which can be used to get the npc's squad id or object id for task_giver_id function give_task(actor, obj, p) if p[1] == nil then printf("No parameter in give_task function.") end task_manager.get_task_manager():give_task(p[1]) end function set_active_task(actor, npc, p) if(p[1]) then local t = db.actor:get_task(tostring(p[1]), true) if(t) then db.actor:set_active_task(t) end end end function set_task_completed(actor,npc,p) if (p[1]) then task_manager.get_task_manager():set_task_completed(p[1]) end end function set_task_failed(actor,npc,p) if (p[1]) then task_manager.get_task_manager():set_task_failed(p[1]) end end -- Функции для работы с отношениями function actor_friend(actor, npc) printf("_bp: xr_effects: actor_friend(): npc='%s': time=%d", npc:name(), time_global()) npc:force_set_goodwill( 1000, actor) end function actor_neutral(actor, npc) npc:force_set_goodwill( 0, actor) end function actor_enemy(actor, npc) npc:force_set_goodwill( -1000, actor) end function set_speaker_as_enemy(actor, npc) npc:force_set_goodwill( -5000, actor) end function set_squad_neutral_to_actor(actor, npc, p) local story_id = p[1] local squad = get_story_squad(story_id) if squad == nil then printf("There is no squad with id[%s]", tostring(story_id)) return end squad:set_squad_relation("neutral") end function set_squad_friend_to_actor(actor, npc, p) local story_id = p[1] local squad = get_story_squad(story_id) if squad == nil then printf("There is no squad with id[%s]", tostring(story_id)) return end squad:set_squad_relation("friend") end --Сделать актера врагом к отряду, передается имя отряда function set_squad_enemy_to_actor( actor, npc, p) local story_id = p[1] local squad = get_story_squad(story_id) if squad == nil then printf("There is no squad with id[%s]", tostring(story_id)) return end squad:set_squad_relation("enemy") end --[[ function set_friends(actor, npc, p) local npc1 for i, v in pairs(p) do npc1 = get_story_object(v) if npc1 and npc1:alive() then --printf("_bp: %d:set_friends(%d)", npc:id(), npc1:id()) npc:set_relation(game_object.friend, npc1) npc1:set_relation(game_object.friend, npc) end end end function set_enemies(actor, npc, p) local npc1 for i, v in pairs(p) do --printf("_bp: set_enemies(%d)", v) npc1 = get_story_object(v) if npc1 and npc1:alive() then npc:set_relation(game_object.enemy, npc1) npc1:set_relation(game_object.enemy, npc) end end end function set_gulag_relation_actor(actor, npc, p) if(p[1]) and (p[2]) then game_relations.set_gulag_relation_actor(p[1], p[2]) end end function set_factions_community(actor, npc, p) if(p[1]~=nil) and (p[2]~=nil) and (p[3]~=nil) then game_relations.set_factions_community(p[1], p[2], p[3]) end end function set_squad_community_goodwill(actor, npc, p) if(p[1]~=nil) and (p[2]~=nil) and (p[3]~=nil) then game_relations.set_squad_community_goodwill(p[1], p[2], p[3]) end end ]]-- --sets NPC relation to actor --set_npc_sympathy(number) --call only from npc`s logic function set_npc_sympathy(actor, npc, p) if(p[1]~=nil) then game_relations.set_npc_sympathy(npc, p[1]) end end --sets SQUAD relation to actor --set_squad_goodwill(faction:number) function set_squad_goodwill(actor, npc, p) if(p[1]~=nil) and (p[2]~=nil) then game_relations.set_squad_goodwill(p[1], p[2]) end end function set_squad_goodwill_to_npc(actor, npc, p) if(p[1]~=nil) and (p[2]~=nil) then game_relations.set_squad_goodwill_to_npc(npc, p[1], p[2]) end end function inc_faction_goodwill_to_actor(actor, npc, p) local id = actor:id() local community = p[1] local delta = p[2] if delta and community then game_relations.change_factions_community_num(community, id, tonumber(delta)) printdbg("/ Goodwill (main) gained with %s: %s", community, delta) else printe("!Wrong parameters in function 'inc_faction_goodwill_to_actor'") return end delta = tonumber(delta) local is_gain = ((delta) > 0) and true or false local delta_b = math.abs(delta) local delta_b2 = math.ceil(delta_b * 0.5) local delta_b3 = math.ceil(delta_b * 0.8) local delta_rnd = ((delta_b) > 1) and math.random(delta_b2,delta_b3) or delta_b local delta_rnd_sub = delta_b - delta_rnd local pass_natural, pass_enemy local rnd_enemy = game_relations.get_random_enemy_faction(community) local rnd_natural = game_relations.get_random_natural_faction(community) if is_gain and delta_rnd and delta_rnd_sub then if rnd_enemy and (delta_rnd > 0) and (relation_registry.community_goodwill(rnd_enemy, id) > 0) then game_relations.change_factions_community_num(rnd_enemy, id, ((-1) * delta_rnd ) ) pass_enemy = true printdbg("/ Goodwill (side) lost with %s: %s", rnd_enemy, ((-1) * delta_rnd )) end if rnd_natural and (delta_rnd_sub > 0) and (relation_registry.community_goodwill(rnd_natural, id) > 0) then game_relations.change_factions_community_num(rnd_natural, id, (delta_rnd_sub ) ) pass_natural = true printdbg("/ Goodwill (side) gained with %s: %s", rnd_natural, (delta_rnd_sub )) end end if community and p[3] then dialogs_mlr.show_goodwill_change_message( community, (pass_natural and rnd_natural or nil), (pass_enemy and rnd_enemy or nil), is_gain ) end end function dec_faction_goodwill_to_actor(actor, npc, p) local community = p[1] local delta = p[2] if delta and community then game_relations.change_factions_community_num(community,actor:id(), -tonumber(delta)) else printf("Wrong parameters in function 'dec_faction_goodwill_to_actor'") end end --[[ function add_custom_static(actor, npc, p) if p[1] ~= nil and p[2] ~= nil then get_hud():AddCustomStatic(p[1], true) get_hud():GetCustomStatic(p[1]):wnd():SetTextST(p[2]) else printf("Invalid parameters in function add_custom_static!!!") end end function remove_custom_static(actor, npc, p) if p[1] ~= nil then get_hud():RemoveCustomStatic(p[1]) else printf("Invalid parameters in function remove_custom_static!!!") end end ]]-- function kill_actor(actor, npc) db.actor:kill(db.actor) end ----------------------------------------------------------------------- -- Treasures support ----------------------------------------------------------------------- function give_treasure (actor, npc, p) end --[[ function change_tsg(actor, npc, p) npc:change_team(p[1], p[2], p[3]) end function exit_game(actor, npc) exec_console_cmd("quit") end ]]-- function start_surge(actor, npc, p) surge_manager.start_surge(p) end function stop_surge(actor, npc, p) surge_manager.stop_surge() end function set_surge_mess_and_task(actor, npc, p) if(p) then surge_manager.set_surge_message(p[1]) if(p[2]) then surge_manager.set_surge_task(p[2]) end end end --[[ function enable_level_changer(actor, npc, p) if(p[1]~=nil) then local obj = get_story_object(p[1]) if(obj) then if db.storage[obj:id()] and db.storage[obj:id()].s_obj then db.storage[obj:id()].s_obj.enabled = true db.storage[obj:id()].s_obj.hint = "level_changer_invitation" else return end obj:enable_level_changer(true) level_tasks.add_lchanger_location() obj:set_level_changer_invitation("level_changer_invitation") end end end function disable_level_changer(actor, npc, p) if(p[1]~=nil) then local obj = get_story_object(p[1]) if(obj) then if not(db.storage[obj:id()] and db.storage[obj:id()].s_obj) then return end obj:enable_level_changer(false) level_tasks.del_lchanger_mapspot(tonumber(p[1])) db.storage[obj:id()].s_obj.enabled = false if(p[2]==nil) then obj:set_level_changer_invitation("level_changer_disabled") db.storage[obj:id()].s_obj.hint = "level_changer_disabled" else obj:set_level_changer_invitation(p[2]) db.storage[obj:id()].s_obj.hint = p[2] end end end end function change_actor_community(actor, npc, p) if(p[1]~=nil) then set_actor_true_community(p[1]) end end function set_faction_community_to_actor(actor, npc, p) -- run_string xr_effects.change_actor_community(nil,nil,{"actor_dolg"}) if(p[1]~=nil) and (p[2]~=nil) then local rel = 0 if(p[2]=="enemy") then rel = -3000 elseif(p[2]=="friend") then rel = 1000 end db.actor:set_community_goodwill(p[1], rel) end end function disable_collision(actor, npc) npc:wounded(true) end function enable_collision(actor, npc) npc:wounded(false) end function disable_actor_collision(actor, npc) actor:wounded(true) end function enable_actor_collision(actor, npc) actor:wounded(false) end function relocate_actor_inventory_to_box(actor, npc, p) local function transfer_object_item(item) if item:section() ~= "wpn_binoc" and item:section() ~= "wpn_knife" and item:section() ~= "device_torch" then db.actor:transfer_item(item, inv_box_1) end end inv_box_1 = get_story_object (p[1]) actor:inventory_for_each(transfer_object_item) end ]]-- function make_actor_visible_to_squad(actor,npc,p) local story_id = p and p[1] local squad = get_story_squad(story_id) if squad == nil then printf("There is no squad with id[%s]", story_id) end for k in squad:squad_members() do local obj = level.object_by_id(k.id) if obj ~= nil then obj:make_object_visible_somewhen( db.actor ) end end end function pstor_set(actor,npc,p) p[2] = tonumber(p[2]) if (p[1] and p[2]) then save_var(db.actor,p[1],p[2]) end end function pstor_reset(actor,npc,p) if (p[1]) then save_var(db.actor,p[1],nil) end end function stop_sr_cutscene(actor,npc,p) local obj = db.storage[npc:id()] if(obj.active_scheme~=nil) then obj[obj.active_scheme].signals["cam_effector_stop"] = true end end --[[ function reset_dialog_end_signal(actor, npc, p) local st = db.storage[npc:id()] if(st.active_scheme==nil) then return end if(st[st.active_scheme].signals==nil) then return end st[st.active_scheme].signals["dialog_end"] = nil end function add_map_spot(actor, npc, p) if(p[1]==nil) then printf("Story id for add map spot function is not set") else local story_id = tonumber(p[1]) local id = id_by_sid(story_id) if(id==nil) then local obj = alife_object(p[1]) id = obj and obj.id end if(id~=nil) then if(p[2]==nil) then p[2] = "primary_task_location" end if(p[3]==nil) then p[3] = "default" end if level.map_has_object_spot(id, p[2]) == 0 then level.map_add_object_spot_ser(id, p[2], p[3]) end else printf("Wrong story id or name [%s] for map spot function", tostring(story_id)) end end end function remove_map_spot(actor, npc, p) if(p[1]==nil) then printf("Story id for add map spot function is not set") else local story_id = tonumber(p[1]) local id = id_by_sid(story_id) if(id==nil) then local obj = alife_object(p[1]) id = obj and obj.id end if(id~=nil) then if(p[2]==nil) then p[2] = "primary_task_location" end if level.map_has_object_spot(id, p[2]) ~= 0 then level.map_remove_object_spot(id, p[2]) end else printf("Wrong story id or name [%s] for map spot function", tostring(story_id)) end end end ]]-- -- add map spot from logic -- param 1 is story_id of object to show on pda map -- param 2 is ui icon tag from map_spots.xml -- param 3 is name of ui_st_pda.xml string function add_map_spot(actor, npc, p) if(p[1]==nil) then printf("Story id for add map spot function is not set") else -- local story_id = tonumber(p[1]) --original SOC/CS local story_id = p[1] -- local id = id_by_sid(story_id) --original SOC/CS local id = get_story_object_id(story_id) if(id==nil) then local obj = alife_object(p[1]) id = obj and obj.id end if(id~=nil) then if(p[2]==nil) then p[2] = "primary_object" end if(p[3]==nil) then p[3] = "default" end if level.map_has_object_spot(id, p[2]) == 0 then level.map_add_object_spot_ser(id, p[2], p[3]) end else printf("Wrong story id or name [%s] for map spot function", tostring(story_id)) end end end -- remove map spot from logic -- param 1 is story_id of object to show on pda map -- param 2 is ui icon tag from map_spots.xml function remove_map_spot(actor, npc, p) if(p[1]==nil) then printf("Story id for add map spot function is not set") else -- local story_id = tonumber(p[1]) --original SOC/CS local story_id = p[1] -- local id = id_by_sid(story_id) --original SOC/CS local id = get_story_object_id(story_id) if(id==nil) then local obj = alife_object(p[1]) id = obj and obj.id end if(id~=nil) then if(p[2]==nil) then p[2] = "primary_object" end if level.map_has_object_spot(id, p[2]) ~= 0 then level.map_remove_object_spot(id, p[2]) end else printf("Wrong story id or name [%s] for map spot function", tostring(story_id)) end end end function show_csky_squads_on_map(actor, npc) local csky_squads_tbl = { {target="csky_sim_squad_novice", hint="csky"}, {target="csky_sim_squad_advanced", hint="csky"}, {target="csky_sim_squad_veteran", hint="csky"} } if (squad.player_id == "csky") then for k,v in pairs(csky_squads_tbl) do local obj_id = get_story_squad(v.target) if(obj_id) then level.map_add_object_spot_ser(obj_id, "alife_presentation_squad_friend_1", v.hint) end end end end function make_actor_visible_to_npc(actor, npc, p) local act = db.actor if act then npc:make_object_visible_somewhen(act) end end -- Anomal fields support function enable_anomaly(actor, npc, p) if p[1] == nil then printf("Story id for enable_anomaly function is not set") end local obj = get_story_object(p[1]) if not obj then printf("There is no object with story_id %s for enable_anomaly function", tostring(p[1])) end obj:enable_anomaly() end function disable_anomaly(actor, npc, p) if p[1] == nil then printf("Story id for disable_anomaly function is not set") end local obj = get_story_object(p[1]) if not obj then printf("There is no object with story_id %s for disable_anomaly function", tostring(p[1])) end obj:disable_anomaly() end function launch_signal_rocket(actor, obj, p) if p==nil then printf("Signal rocket name is not set!") end if db.signal_light[p[1]] then db.signal_light[p[1]]:launch() else printf("No such signal rocket: [%s] on level", tostring(p[1])) end end --[[ function reset_faction_goodwill(actor, obj, p) if db.actor and p[1] then local board = SIMBOARD local faction = board.players[ p[1] ] if faction then db.actor:set_community_goodwill(p[1], 0) end end end ]]-- function add_cs_text(actor, npc, p) if p[1] then local hud = get_hud() if (hud) then local cs_text = hud:GetCustomStatic("text_on_screen_center") if cs_text then hud:RemoveCustomStatic("text_on_screen_center") end hud:AddCustomStatic("text_on_screen_center", true) cs_text = hud:GetCustomStatic("text_on_screen_center") cs_text:wnd():TextControl():SetText(game.translate_string(p[1])) end end end function del_cs_text(actor, npc, p) local hud = get_hud() if (hud) then cs_text = hud:GetCustomStatic("text_on_screen_center") if cs_text then hud:RemoveCustomStatic("text_on_screen_center") end end end function spawn_item_to_npc(actor, npc, p) local new_item = p[1] if p[1] then alife_create(new_item, npc:position(), npc:level_vertex_id(), npc:game_vertex_id(), npc:id()) end end function give_money_to_npc(actor, npc, p) local money = p[1] and tonumber(p[1]) if money then npc:give_money(money) end end function seize_money_to_npc(actor, npc, p) local money = p[1] and tonumber(p[1]) if money then npc:give_money(-money) end end -- Передача предмета от непися к неписю -- relocate_item(item_name:story_id_from:story_id_to) function relocate_item(actor, npc, p) local item = p and p[1] local from_obj = p and get_story_object(p[2]) local to_obj = p and get_story_object(p[3]) if to_obj ~= nil then if from_obj ~= nil and from_obj:object(item) ~= nil then from_obj:transfer_item(from_obj:object(item), to_obj) else alife_create(item, to_obj:position(), to_obj:level_vertex_id(), to_obj:game_vertex_id(), to_obj:id()) end else printf("Couldn't relocate item to NULL") end end -- Сделать сквады врагами, передаются два сквада set_squads_enemies(squad_name_1:squad_name_2) function set_squads_enemies(actor, npc, p) if (p[1] == nil or p[2] == nil) then printf("Wrong parameters in function set_squad_enemies") return end local squad_1 = get_story_squad(p[1]) local squad_2 = get_story_squad(p[2]) if squad_1 == nil then assert("There is no squad with id[%s]", tostring(p[1])) return end if squad_2 == nil then assert("There is no squad with id[%s]", tostring(p[2])) return end for k in squad_1:squad_members() do local npc_obj_1 = db.storage[k.id] and db.storage[k.id].object if npc_obj_1 ~= nil then for kk in squad_2:squad_members() do local npc_obj_2 = db.storage[kk.id] and db.storage[kk.id].object if npc_obj_2 ~= nil then npc_obj_1:set_relation(game_object.enemy, npc_obj_2) npc_obj_2:set_relation(game_object.enemy, npc_obj_1) printf("set_squads_enemies: %d:set_enemy(%d)", npc_obj_1:id(), npc_obj_2:id()) end end end end end local particles_table = { [1] = {particle = particles_object("anomaly2\\teleport_out_00"), sound = sound_object("anomaly\\teleport_incoming")}, [2] = {particle = particles_object("anomaly2\\teleport_out_00"), sound = sound_object("anomaly\\teleport_incoming")}, [3] = {particle = particles_object("anomaly2\\teleport_out_00"), sound = sound_object("anomaly\\teleport_incoming")}, [4] = {particle = particles_object("anomaly2\\teleport_out_00"), sound = sound_object("anomaly\\teleport_incoming")}, } function jup_b16_play_particle_and_sound(actor, npc, p) particles_table[p[1]].particle :play_at_pos(patrol(npc:name().."_particle"):point(0)) --particles_table[p[1]].sound :play_at_pos(actor, patrol(npc:name().."_particle"):point(0), 0, sound_object.s3d) end --Функция установки состояния видимости кровососа. -- Возможный набор параметров --> story_id:visibility_state(можно вызывать откуда угодно) или visibility_state(если вызывается из кастомдаты кровососа) -- visibility_state --> -- 0 - невидимый -- 1 - полувидимый -- 2 - полностью видимый function set_bloodsucker_state(actor, npc, p) if (p and p[1]) == nil then printf("Wrong parameters in function 'set_bloodsucker_state'!!!") end local state = p[1] if p[2] ~= nil then state = p[2] npc = get_story_object(p[1]) end if npc ~= nil then if state == "default" then npc:force_visibility_state(-1) else npc:force_visibility_state(tonumber(state)) end end end --Функция вставки предмета в определенную точку, сделал для сцены б57 function drop_object_item_on_point(actor, npc, p) local drop_object = db.actor:object(p[1]) local drop_point = patrol(p[2]):point(0) db.actor:drop_item_and_teleport(drop_object, drop_point) end --Функция отнятия предмета у игрока function remove_item(actor, npc, p) local sec = p[1] if not (sec) then printf("Wrong parameters in function 'remove_item'!!!") return end local amt = p[2] and tonumber(p[2]) or 1 local removed = 0 local se_item local function release_actor_item(temp, item) if (item:section() == sec and amt > 0) then se_item = alife_object(item:id()) if (se_item) then alife_release(se_item) amt = amt - 1 removed = removed + 1 end end end db.actor:iterate_inventory(release_actor_item,nil) if (removed > 0) then news_manager.relocate_item(db.actor,"out",sec,removed) end end -- Сюжетное сохранение в важных местах function scenario_autosave(actor, npc, p) local save_name = p[1] if save_name == nil then printf("You are trying to use scenario_autosave without save name") end --[[ clear excess corpses everytime player saves --release_body_manager.get_release_body_manager():clear() if (IsImportantSave()) and (not ui_options.get("other/important_save")) then local prefix = user_name() local save_param = prefix.." - "..game.translate_string(save_name) exec_console_cmd("save "..save_param) end --]] end function zat_b29_create_random_infop(actor, npc, p) if p[2] == nil then printf("Not enough parameters for zat_b29_create_random_infop!") end local amount_needed = p[1] local current_infop = 0 local total_infop = 0 if (not amount_needed or amount_needed == nil) then amount_needed = 1 end for k,v in pairs(p) do if k > 1 then total_infop = total_infop + 1 disable_info(v) end end if amount_needed > total_infop then amount_needed = total_infop end for i = 1, amount_needed do current_infop = math.random(1, total_infop) for k,v in pairs(p) do if k > 1 then if (k == current_infop + 1 and (not has_alife_info(v))) then db.actor:give_info_portion(v) break end end end end end function give_item_b29(actor, npc, p) -- local story_object = p and get_story_object(p[1]) local az_name local az_table = { "zat_b55_anomal_zone", "zat_b54_anomal_zone", "zat_b53_anomal_zone", "zat_b39_anomal_zone", "zaton_b56_anomal_zone", } for i = 16, 23 do if has_alife_info(dialogs_zaton.zat_b29_infop_bring_table[i]) then for k,v in pairs(az_table) do if has_alife_info(v) then az_name = v disable_info(az_name) break end end pick_artefact_from_anomaly(nil, nil, {p[1], az_name, dialogs_zaton.zat_b29_af_table[i]}) break end end end function relocate_item_b29(actor, npc, p) local item for i = 16, 23 do if has_alife_info(dialogs_zaton.zat_b29_infop_bring_table[i]) then item = dialogs_zaton.zat_b29_af_table[i] break end end local from_obj = p and get_story_object(p[1]) local to_obj = p and get_story_object(p[2]) if to_obj ~= nil then if from_obj ~= nil and from_obj:object(item) ~= nil then from_obj:transfer_item(from_obj:object(item), to_obj) else alife_create(item, to_obj:position(), to_obj:level_vertex_id(), to_obj:game_vertex_id(), to_obj:id()) end else printf("Couldn't relocate item to NULL") end end -- Функция ресетит секвенсную звукокую тему у непися. by peacemaker, hein, redstain function reset_sound_npc(actor, npc, p) local obj_id = npc:id() if obj_id and xr_sound.sound_table and xr_sound.sound_table[obj_id] then xr_sound.sound_table[obj_id]:reset(obj_id) end end function jup_b202_inventory_box_relocate(actor, npc) local inv_box_out = get_story_object("jup_b202_actor_treasure") local inv_box_in = get_story_object("jup_b202_snag_treasure") local items_to_relocate = {} local function relocate(inv_box_out, item) items_to_relocate[#items_to_relocate+1] = item end inv_box_out:iterate_inventory_box (relocate, inv_box_out) for k,v in ipairs(items_to_relocate) do inv_box_out:transfer_item(v, inv_box_in) end end function clear_box(actor, npc, p) if (p and p[1]) == nil then printf("Wrong parameters in function 'clear_box'!!!") end local inv_box = get_story_object(p[1]) if inv_box == nil then printf("There is no object with story_id [%s]", tostring(p[1])) end local items_table = {} local function add_items(inv_box, item) items_table[#items_table+1] = item end inv_box:iterate_inventory_box(add_items, inv_box) local sim = alife() for k,v in pairs(items_table) do alife_release_id(v:id()) end end function activate_weapon(actor, npc, p) local object = actor:object(p[1]) if object == nil then assert("Actor has no such weapon! [%s]", p[1]) end if object ~= nil then actor:make_item_active(object) end end function set_game_time(actor, npc, p) local real_hours = level.get_time_hours() local real_minutes = level.get_time_minutes() local hours = tonumber(p[1]) local minutes = tonumber(p[2]) if p[2] == nil then minutes = 0 end local hours_to_change = hours - real_hours if hours_to_change <= 0 then hours_to_change = hours_to_change + 24 end local minutes_to_change = minutes - real_minutes if minutes_to_change <= 0 then minutes_to_change = minutes_to_change + 60 hours_to_change = hours_to_change - 1 elseif hours == real_hours then hours_to_change = hours_to_change - 24 end level.change_game_time(0,hours_to_change,minutes_to_change) level_weathers.get_weather_manager():forced_weather_change() surge_manager.SurgeManager.time_forwarded = true printf("set_game_time: time changed to [%d][%d]", hours_to_change, minutes_to_change) end function forward_game_time(actor, npc, p) if not p then printf("Insufficient or invalid parameters in function 'forward_game_time'!") end local hours = tonumber(p[1]) local minutes = tonumber(p[2]) if p[2] == nil then minutes = 0 end level.change_game_time(0,hours,minutes) level_weathers.get_weather_manager():forced_weather_change() surge_manager.SurgeManager.time_forwarded = true printf("forward_game_time: time forwarded on [%d][%d]", hours, minutes) end function stop_tutorial() --printf("stop tutorial called") game.stop_tutorial() end function jup_b10_spawn_drunk_dead_items(actor, npc, p) local items_all = { ["wpn_ak74"] = 1, ["ammo_5.45x39_fmj"] = 5, ["ammo_5.45x39_ap"] = 3, ["wpn_fort"] = 1, ["ammo_9x18_fmj"] = 3, ["ammo_12x70_buck"] = 5, ["ammo_11.43x23_hydro"] = 2, ["grenade_rgd5"] = 3, ["grenade_f1"] = 2, ["medkit_army"] = 2, ["medkit"] = 4, ["bandage"] = 4, ["antirad"] = 2, ["vodka"] = 3, ["energy_drink"] = 2, ["conserva"] = 1, ["jup_b10_ufo_memory_2"] = 1, } local items = { [2] = { ["wpn_sig550_luckygun"] = 1, }, [1] = { ["ammo_5.45x39_fmj"] = 5, ["ammo_5.45x39_ap"] = 3, ["wpn_fort"] = 1, ["ammo_9x18_fmj"] = 3, ["ammo_12x70_buck"] = 5, ["ammo_11.43x23_hydro"] = 2, ["grenade_rgd5"] = 3, ["grenade_f1"] = 2, }, [0] = { ["medkit_army"] = 2, ["medkit"] = 4, ["bandage"] = 4, ["antirad"] = 2, ["vodka"] = 3, ["energy_drink"] = 2, ["conserva"] = 1, }, } if p and p[1] ~= nil then local cnt = load_var(actor, "jup_b10_ufo_counter", 0) if cnt > 2 then return end for k,v in pairs(items[cnt]) do local target_obj_id = get_story_object_id(p[1]) if target_obj_id ~= nil then box = alife_object(target_obj_id) if box == nil then printf("There is no such object %s", p[1]) end for i = 1,v do alife_create(k,vector(),0,0,target_obj_id) end else printf("object is nil %s", tostring(p[1])) end end else for k,v in pairs(items_all) do for i = 1,v do alife_create(k, npc:position(), npc:level_vertex_id(), npc:game_vertex_id(), npc:id()) end end end end function pick_artefact_from_anomaly(actor, npc, p) local se_obj local az_name = p and p[2] local af_name = p and p[3] local af_id local af_obj local anomal_zone = db.anomaly_by_name[az_name] if p and p[1] then -- if p[1] == "actor" then -- npc = db.actor -- else -- npc = get_story_object(p[1]) -- end local npc_id = get_story_object_id(p[1]) if npc_id == nil then printf("Couldn't relocate item to NULL in function 'pick_artefact_from_anomaly!'") end se_obj = alife_object(npc_id) if se_obj and (not IsStalker(nil,se_obj:clsid()) or not se_obj:alive()) then printf("Couldn't relocate item to NULL (dead or not stalker) in function 'pick_artefact_from_anomaly!'") end end if anomal_zone == nil then printf("No such anomal zone in function 'pick_artefact_from_anomaly!'") end if anomal_zone.spawned_count < 1 then printf("No artefacts in anomal zone [%s]", az_name) return end for k,v in pairs(anomal_zone.artefact_ways_by_id) do if alife_object(tonumber(k)) and af_name == alife_object(tonumber(k)):section_name() then af_id = tonumber(k) af_obj = alife_object(tonumber(k)) break end if af_name == nil then af_id = tonumber(k) af_obj = alife_object(tonumber(k)) af_name = af_obj:section_name() break end end if af_id == nil then printf("No such artefact [%s] found in anomal zone [%s]", tostring(af_name), az_name) return end anomal_zone:on_artefact_take(af_obj) alife_release(af_obj) give_item(db.actor, se_obj, {af_name, p[1]}) -- alife_create(af_name, -- npc.position, -- npc.level_vertex_id, -- npc.game_vertex_id, -- npc.id) end function anomaly_turn_off (actor, npc, p) local anomal_zone = db.anomaly_by_name[p[1]] if anomal_zone == nil then printf("No such anomal zone in function 'anomaly_turn_off!'") end anomal_zone:turn_off() end function anomaly_turn_on (actor, npc, p) local anomal_zone = db.anomaly_by_name[p[1]] if anomal_zone == nil then printf("No such anomal zone in function 'anomaly_turn_on!'") end if p[2] then anomal_zone:turn_on(true) else anomal_zone:turn_on(false) end end function zat_b202_spawn_random_loot(actor, npc, p) local si_table = {} si_table[1] = { [1] = {item = {"bandage","bandage","bandage","bandage","bandage","medkit","medkit","medkit","conserva","conserva"}}, [2] = {item = {"medkit","medkit","medkit","medkit","medkit","vodka","vodka","vodka","kolbasa","kolbasa"}}, [3] = {item = {"antirad","antirad","antirad","medkit","medkit","bandage","kolbasa","kolbasa","conserva"}}, } si_table[2] = { [1] = {item = {"grenade_f1","grenade_f1","grenade_f1"}}, [2] = {item = {"grenade_rgd5","grenade_rgd5","grenade_rgd5","grenade_rgd5","grenade_rgd5"}} } si_table[3] = { [1] = {item = {"detector_elite"}}, [2] = {item = {"detector_advanced"}} } si_table[4] = { [1] = {item = {"helm_hardhat"}}, [2] = {item = {"helm_respirator"}} } si_table[5] = { [1] = {item = {"wpn_val","ammo_9x39_ap","ammo_9x39_ap","ammo_9x39_ap"}}, [2] = {item = {"wpn_spas12","ammo_12x70_buck","ammo_12x70_buck","ammo_12x70_buck","ammo_12x70_buck"}}, [3] = {item = {"wpn_desert_eagle","ammo_11.43x23_fmj","ammo_11.43x23_fmj","ammo_11.43x23_hydro","ammo_11.43x23_hydro"}}, [4] = {item = {"wpn_abakan","ammo_5.45x39_ap","ammo_5.45x39_ap"}}, [5] = {item = {"wpn_sig550","ammo_5.56x45_ap","ammo_5.56x45_ap"}}, [6] = {item = {"wpn_ak74","ammo_5.45x39_fmj","ammo_5.45x39_fmj"}}, [7] = {item = {"wpn_l85","ammo_5.56x45_ss190","ammo_5.56x45_ss190"}} } si_table[6] = { [1] = {item = {"specops_outfit"}}, [2] = {item = {"stalker_outfit"}} } weight_table = {} weight_table[1] = 2 weight_table[2] = 2 weight_table[3] = 2 weight_table[4] = 2 weight_table[5] = 4 weight_table[6] = 4 local spawned_item = {} local max_weight = 12 repeat local n = 0 repeat n = math.random(1, #weight_table) local prap = true for k,v in pairs(spawned_item) do if v == n then prap = false break end end until (prap) and ((max_weight - weight_table[n]) >= 0) max_weight = max_weight - weight_table[n] spawned_item[#spawned_item+1] = n local item = math.random(1, #si_table[n]) for k,v in pairs(si_table[n][item].item) do spawn_object_in(actor, npc, {tostring(v),"jup_b202_snag_treasure"}) end until max_weight <= 0 end function zat_a1_tutorial_end_give(actor, npc) -- level.add_pp_effector("black.ppe", 1313, true) ---do not stop on r1 ! db.actor:give_info_portion("zat_a1_tutorial_end") end function oasis_heal() local d_health = 0.005 local d_power = 0.01 local d_bleeding = 0.05 local d_radiation = -0.05 if(db.actor.health<1) then db.actor:change_health(d_health) end if(db.actor.power<1) then db.actor:change_power(d_power) end if(db.actor.radiation>0) then db.actor:change_radiation(d_radiation) end if(db.actor.bleeding>0) then db.actor.bleeding = d_bleeding end db.actor:change_satiety(0.01) end --Функция принимает только одно значение, определяющее для какой групировки запускается. доступные значения [duty, freedom] function jup_b221_play_main(actor, npc, p) local info_table = {} local main_theme local reply_theme local info_need_reply local reachable_theme = {} local theme_to_play = 0 if (p and p[1]) == nil then printf("No such parameters in function 'jup_b221_play_main'") end --Составляем таблицу инфопоршинов определяющих доступность той или иной темы, определяем префиксы темы, ответа и реакции, соответственно для долга или для свободы. if tostring(p[1]) == "duty" then info_table = { [1] = "jup_b25_freedom_flint_gone", [2] = "jup_b25_flint_blame_done_to_duty", [3] = "jup_b4_monolith_squad_in_duty", [4] = "jup_a6_duty_leader_bunker_guards_work", [5] = "jup_a6_duty_leader_employ_work", [6] = "jup_b207_duty_wins" } main_theme = "jup_b221_duty_main_" reply_theme = "jup_b221_duty_reply_" info_need_reply = "jup_b221_duty_reply" elseif tostring(p[1]) == "freedom" then info_table = { [1] = "jup_b207_freedom_know_about_depot", [2] = "jup_b46_duty_founder_pda_to_freedom", [3] = "jup_b4_monolith_squad_in_freedom", [4] = "jup_a6_freedom_leader_bunker_guards_work", [5] = "jup_a6_freedom_leader_employ_work", [6] = "jup_b207_freedom_wins" } main_theme = "jup_b221_freedom_main_" reply_theme = "jup_b221_freedom_reply_" info_need_reply = "jup_b221_freedom_reply" else printf("Wrong parameters in function 'jup_b221_play_main'") end --Составляем таблицу достыпных тем(тлько номера тем). for k,v in pairs(info_table) do if (has_alife_info(v)) and (not has_alife_info(main_theme .. tostring(k) .. "_played")) then table.insert(reachable_theme,k) -- printf("jup_b221_play_main: table reachable_theme ------------------------------> [%s]", tostring(k)) end end --Если таблица доступных тем пуста играем ответ. Если же она не пуста играем основную тему. Если играем основную тему заносим значение счетчика для повторного выполнения функции. Тему выбираем по рандому. if #reachable_theme ~= 0 then disable_info(info_need_reply) theme_to_play = reachable_theme[math.random(1, #reachable_theme)] -- printf("jup_b221_play_main: variable theme_to_play ------------------------------> [%s]", tostring(theme_to_play)) save_var(actor,"jup_b221_played_main_theme",tostring(theme_to_play)) db.actor:give_info_portion(main_theme .. tostring(theme_to_play) .."_played") if theme_to_play ~= 0 then play_sound(actor, npc, {main_theme .. tostring(theme_to_play)}) else printf("No such theme_to_play in function 'jup_b221_play_main'") end else db.actor:give_info_portion(info_need_reply) theme_to_play = tonumber(load_var(actor,"jup_b221_played_main_theme",0)) if theme_to_play ~= 0 then play_sound(actor, npc, {reply_theme..tostring(theme_to_play)}) else printf("No such theme_to_play in function 'jup_b221_play_main'") end save_var(actor,"jup_b221_played_main_theme","0") end end function pas_b400_play_particle(actor, npc, p) db.actor:start_particles("zones\\zone_acidic_idle","bip01_head") end function pas_b400_stop_particle(actor, npc, p) db.actor:stop_particles("zones\\zone_acidic_idle","bip01_head") end function damage_pri_a17_gauss() local obj = get_story_object("pri_a17_gauss_rifle") --local obj = npc:object("pri_a17_gauss_rifle") if obj ~= nil then obj:set_condition(0.0) end end function pri_a17_hard_animation_reset(actor, npc, p) --db.storage[npc:id()].state_mgr:set_state("pri_a17_fall_down", nil, nil, nil, {fast_set = true}) db.storage[npc:id()].state_mgr:set_state("pri_a17_fall_down") local state_mgr = db.storage[npc:id()].state_mgr if state_mgr ~= nil then state_mgr.animation:set_state(nil, true) state_mgr.animation:set_state("pri_a17_fall_down") state_mgr.animation:set_control() end end function jup_b217_hard_animation_reset(actor, npc, p) db.storage[npc:id()].state_mgr:set_state("jup_b217_nitro_straight") local state_mgr = db.storage[npc:id()].state_mgr if state_mgr ~= nil then state_mgr.animation:set_state(nil, true) state_mgr.animation:set_state("jup_b217_nitro_straight") state_mgr.animation:set_control() end end --[[ function set_tip_to_story(actor, npc, p) if p == nil or p[2] == nil then printf("Not enough parameters in 'set_tip_to_story' function!") end local obj = get_story_object(p[1]) if not obj then return end local tip = p[2] obj:set_tip_text(tip) end function clear_tip_from_story(actor, npc, p) if p == nil or p[1] == nil then printf("Not enough parameters in 'clear_tip_from_story' function!") end local obj = get_story_object(p[1]) if not obj then return end obj:set_tip_text("") end ]]-- function mech_discount(actor, npc, p) if(p[1]) then inventory_upgrades.mech_discount(tonumber(p[1]) or 1) end end function polter_actor_ignore(actor, npc, p) if p[1] and p[1] == "true" then npc:poltergeist_set_actor_ignore(true) elseif p[1] and p[1] == "false" then npc:poltergeist_set_actor_ignore(false) end end function burer_force_gravi_attack(actor, npc) npc:burer_set_force_gravi_attack(true) end function burer_force_anti_aim(actor, npc) npc:set_force_anti_aim(true) end function show_freeplay_dialog(actor, npc, p) if p[1] and p[2] and p[2] == "true" then ui_freeplay_dialog.show("message_box_yes_no", p[1]) elseif p[1] then ui_freeplay_dialog.show("message_box_ok", p[1]) end end -- Только для state_mgr function get_best_detector(npc) local detectors = { "detector_simple", "detector_advanced", "detector_elite", "detector_scientific" } for k,v in pairs(detectors) do local obj = npc:object(v) if obj ~= nil then obj:enable_attachable_item(true) return end end end function hide_best_detector(npc) local detectors = { "detector_simple", "detector_advanced", "detector_elite", "detector_scientific" } for k,v in pairs(detectors) do local obj = npc:object(v) if obj ~= nil then obj:enable_attachable_item(false) return end end end -- Инфопоршны для синхронизации анимации нпс с прочими действиями, и для других целей function pri_a18_radio_start(actor, npc) db.actor:give_info_portion("pri_a18_radio_start") end function pri_a17_ice_climb_end(actor, npc) db.actor:give_info_portion("pri_a17_ice_climb_end") end function jup_b219_opening(actor, npc) db.actor:give_info_portion("jup_b219_opening") end function jup_b219_entering_underpass(actor, npc) db.actor:give_info_portion("jup_b219_entering_underpass") end function pri_a17_pray_start(actor, npc) db.actor:give_info_portion("pri_a17_pray_start") end function zat_b38_open_info(actor, npc) db.actor:give_info_portion("zat_b38_open_info") end function zat_b38_switch_info(actor, npc) db.actor:give_info_portion("zat_b38_switch_info") end function zat_b38_cop_dead(actor, npc) db.actor:give_info_portion("zat_b38_cop_dead") end function jup_b15_zulus_drink_anim_info(actor, npc) db.actor:give_info_portion("jup_b15_zulus_drink_anim_info") end function pri_a17_preacher_death(actor, npc) db.actor:give_info_portion("pri_a17_preacher_death") end function zat_b3_tech_surprise_anim_end(actor, npc) db.actor:give_info_portion("zat_b3_tech_surprise_anim_end") end function zat_b3_tech_waked_up(actor, npc) db.actor:give_info_portion("zat_b3_tech_waked_up") end function zat_b3_tech_drinked_out(actor, npc) db.actor:give_info_portion("zat_b3_tech_drinked_out") end function pri_a28_kirillov_hq_online(actor, npc) db.actor:give_info_portion("pri_a28_kirillov_hq_online") end function pri_a20_radio_start(actor, npc) db.actor:give_info_portion("pri_a20_radio_start") end function pri_a22_kovalski_speak(actor, npc) db.actor:give_info_portion("pri_a22_kovalski_speak") end function zat_b38_underground_door_open(actor, npc) db.actor:give_info_portion("zat_b38_underground_door_open") end function zat_b38_jump_tonnel_info(actor, npc) db.actor:give_info_portion("zat_b38_jump_tonnel_info") end function jup_a9_cam1_actor_anim_end(actor, npc) db.actor:give_info_portion("jup_a9_cam1_actor_anim_end") end function pri_a28_talk_ssu_video_end(actor, npc) db.actor:give_info_portion("pri_a28_talk_ssu_video_end") end function set_torch_state(actor, npc, p) if p == nil or p[2] == nil then printf("Not enough parameters in 'set_torch_state' function!") end local obj = get_story_object(p[1]) if not obj then return end local torch = obj:object("device_torch") if torch then if p[2] == "on" then torch:enable_attachable_item(true) elseif p[2] == "off" then torch:enable_attachable_item(false) end end end local actor_nightvision = false local actor_torch = false function disable_actor_nightvision(actor, npc) local nightvision = db.actor:object("device_torch") if not (nightvision) then return end if nightvision:night_vision_enabled() then nightvision:enable_night_vision(false) actor_nightvision = true end end function enable_actor_nightvision(actor, npc) local nightvision = db.actor:object("device_torch") if not (nightvision) then return end if not nightvision:night_vision_enabled() and actor_nightvision then nightvision:enable_night_vision(true) actor_nightvision = false end end function disable_actor_torch(actor, npc) local torch = db.actor:object("device_torch") if not (torch) then return end if torch:torch_enabled() then torch:enable_torch(false) actor_torch = true end end function enable_actor_torch(actor, npc) local torch = db.actor:object("device_torch") if not (torch) then return end if not torch:torch_enabled() and actor_torch then torch:enable_torch(true) actor_torch = false end end function create_cutscene_actor_with_weapon(actor, npc, p) --' p[1] - секция кого спаунить --' p[2] - имя патрульного пути где спаунить. --' p[3] - точка патрульного пути --' p[4] - поворот по оси Y --' p[5] - принудительный слот - будет работать даже при disable_ui local spawn_sect = p[1] if spawn_sect == nil then printf("Wrong spawn section for 'spawn_object' function %s. For object %s", tostring(spawn_sect), obj:name()) end local path_name = p[2] if path_name == nil then printf("Wrong path_name for 'spawn_object' function %s. For object %s", tostring(path_name), obj:name()) end if not level.patrol_path_exists(path_name) then printf("Path %s doesnt exist. Function 'spawn_object' for object %s ", tostring(path_name), obj:name()) end local ptr = patrol(path_name) local index = p[3] or 0 local yaw = p[4] or 0 local npc = alife_create(spawn_sect, ptr:point(index), ptr:level_vertex_id(0), ptr:game_vertex_id(0)) if IsStalker( nil, npc:clsid()) then npc:o_torso().yaw = yaw * math.pi / 180 else npc.angle.y = yaw * math.pi / 180 end local slot_override = p[5] or 0 local slot local active_item if slot_override == 0 then slot = db.actor:active_slot() if(slot~=2 and slot~=3) then return end active_item = db.actor:active_item() else if db.actor:item_in_slot(slot_override) ~= nil then active_item = db.actor:item_in_slot(slot_override) else if db.actor:item_in_slot(3) ~= nil then active_item = db.actor:item_in_slot(3) elseif db.actor:item_in_slot(2) ~= nil then active_item = db.actor:item_in_slot(2) else return end end end local actor_weapon = alife_object(active_item:id()) local section_name = actor_weapon:section_name() if section_name == "pri_a17_gauss_rifle" then section_name = "wpn_gauss" end if (active_item) then local new_weapon = alife_create(section_name, ptr:point(index), ptr:level_vertex_id(0), ptr:game_vertex_id(0), npc.id) if section_name ~= "wpn_gauss" then new_weapon:clone_addons(actor_weapon) end end end -- Заставить играть уникальные анимации сна(у кровососа) function set_force_sleep_animation(actor, npc, p) local num = p[1] npc:force_stand_sleep_animation(tonumber(num)) end -- Убрать уникальные анимации сна(у кровососа) function release_force_sleep_animation(actor, npc) npc:release_stand_sleep_animation() end function zat_b33_pic_snag_container(actor, npc) if xr_conditions.actor_in_zone(actor, npc, {"zat_b33_tutor"}) then give_actor(actor, npc, {"zat_b33_safe_container"}) db.actor:give_info_portion("zat_b33_find_package") if not has_alife_info("zat_b33_safe_container") then local zone = db.zone_by_name["zat_b33_tutor"] play_sound(actor, zone, {"pda_news"}) end end end --Отключение воздействия вражеского нпс на индикатор видимости врага на хаде игрока. --Исп. только из логики нпс. function set_visual_memory_enabled(actor, npc, p) if (p and p[1]) and (tonumber(p[1]) >= 0) and (tonumber(p[1]) <= 1) then local boolval = false if (tonumber(p[1]) == 1) then boolval = true end npc:set_visual_memory_enabled(boolval) end end function disable_memory_object (actor, npc) local best_enemy = npc:best_enemy() if best_enemy then npc:enable_memory_object(best_enemy, false) end end function zat_b202_spawn_b33_loot(actor, npc, p) local info_table = { "zat_b33_first_item_gived", "zat_b33_second_item_gived", "zat_b33_third_item_gived", "zat_b33_fourth_item_gived", "zat_b33_fifth_item_gived" } local item_table = {} item_table[1] = { "wpn_fort_snag" } item_table[2] = { "medkit_scientic", "medkit_scientic", "medkit_scientic", "antirad", "antirad", "antirad", "bandage", "bandage", "bandage", "bandage", "bandage" } item_table[3] = { "wpn_ak74u_snag" } item_table[4] = { "af_soul" } item_table[5] = { "helm_hardhat_snag" } for k,v in pairs(info_table) do local obj_id if (k == 1) or (k == 3) then obj_id = "jup_b202_stalker_snag" else obj_id = "jup_b202_snag_treasure" end if not has_alife_info(tostring(v)) then for l,m in pairs(item_table[k]) do -- printf("zat_b202_spawn_b33_loot: number [%s] item [%s] to [%s]", tostring(k), tostring(m), tostring(obj_id)) spawn_object_in(actor, npc, {tostring(m),tostring(obj_id)}) end end end end function set_monster_animation (actor, npc, p) if not (p and p[1]) then printf("Wrong parameters in function 'set_monster_animation'!!!") end npc:set_override_animation (p[1]) end function clear_monster_animation (actor, npc) npc:clear_override_animation () end local actor_position_for_restore local actor_direction_for_restore function save_actor_position() actor_position_for_restore = get_story_object("actor"):position() --actor_direction_for_restore = get_story_object("actor"):direction() end function restore_actor_position() --db.actor:set_actor_direction(actor_direction_for_restore) db.actor:set_actor_position(actor_position_for_restore) end function upgrade_hint(actor, npc, p) if(p) then inventory_upgrades.cur_hint = p end end function force_obj(actor, npc, p) local obj = get_story_object(p[1]) if not obj then printf("'force_obj' Target object does not exist") return end if p[2] == nil then p[2] = 20 end if p[3] == nil then p[3] = 100 end obj:set_const_force(VEC_Y, p[2], p[3]) end function pri_a28_check_zones() local story_obj_id local dist local index = 0 local zones_tbl = { [1] = "pri_a28_sr_mono_add_1", [2] = "pri_a28_sr_mono_add_2", [3] = "pri_a28_sr_mono_add_3", } local info_tbl = { [1] = "pri_a28_wave_1_spawned", [2] = "pri_a28_wave_2_spawned", [3] = "pri_a28_wave_3_spawned", } local squad_tbl = { [1] = "pri_a28_heli_mono_add_1", [2] = "pri_a28_heli_mono_add_2", [3] = "pri_a28_heli_mono_add_3", } for k,v in pairs(zones_tbl) do story_obj_id = get_story_object_id(v) if story_obj_id then local se_obj = alife_object(story_obj_id) local curr_dist = se_obj.position:distance_to(db.actor:position()) if index == 0 then dist = curr_dist index = k elseif dist < curr_dist then dist = curr_dist index = k end end end if index == 0 then printf("Found no distance or zones in func 'pri_a28_check_zones'") end if has_alife_info(info_tbl[index]) then for k,v in pairs(info_tbl) do if not has_alife_info(info_tbl[k]) then db.actor:give_info_portion(info_tbl[k]) end end else db.actor:give_info_portion(info_tbl[index]) end create_squad(db.actor,nil,{squad_tbl[index],"pri_a28_heli"}) end function eat_vodka_script() if db.actor:object("vodka_script") ~= nil then db.actor:eat(db.actor:object("vodka_script")) end end local mat_table = { "jup_b200_material_1", "jup_b200_material_2", "jup_b200_material_3", "jup_b200_material_4", "jup_b200_material_5", "jup_b200_material_6", "jup_b200_material_7", "jup_b200_material_8", "jup_b200_material_9", } function jup_b200_count_found(actor) local cnt = 0 for k,v in pairs(mat_table) do local material_obj = get_story_object(v) if material_obj then local parent = material_obj:parent() if parent then local parent_id = parent:id() if parent_id ~= 65535 and parent_id == actor:id() then cnt = cnt + 1 end end end end cnt = cnt + load_var(actor, "jup_b200_tech_materials_brought_counter", 0) save_var(actor, "jup_b200_tech_materials_found_counter", cnt) end function sr_teleport(actor,npc,p) ui_sr_teleport.msg_box_ui(npc,p and p[1],p and p[2]) end function make_a_wish(actor,npc,p) -- /////////////////////////////////////////////////////////////////////////////////////////////// -- -- End Find Wish Granter Storyline Task -- -- Added by DoctorX -- October 13, 2016 -- -- ----------------------------------------------------------------------------------------------- -- Remove on find wish granter infoportion: disable_info( "drx_sl_on_find_wish_granter" ) -- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ local action_list = {} action_list[1] = function() local str = game.translate_string("st_zone_disappeared") error(str,2) return end action_list[2] = function() give_info("actor_made_wish") give_info("actor_made_wish_for_control") return end action_list[3] = function() local sim = alife() local function remove_this_squad(id) local squad = id and sim:object(id) if not (squad) then return true end printf("DEBUG: removing squad %s from the game",squad:name()) SIMBOARD:assign_squad_to_smart(squad, nil) squad:remove_squad() return true end local squad for i=1,65534 do squad = sim:object(i) if (squad and squad:clsid() == clsid.online_offline_group_s) then CreateTimeEvent("remove_this_squad",squad.id,math.random(1,10),remove_this_squad,squad.id) end end give_info("actor_made_wish_for_peace") give_info("actor_made_wish") return end action_list[4] = function() local sim = alife() local s_find = string.find local ltx = ini_file("plugins\\spawner_blacklist.ltx") local pos = db.actor:position() local lid = db.actor:level_vertex_id() local gid = db.actor:game_vertex_id() ini_sys:section_for_each( function(section) local cost = ini_sys:r_float_ex(section,"cost") if cost and cost > 0 and (not ltx:line_exist("ignore_sections",section)) then local parent = ini_sys:r_string_ex(section,"parent_section") local qst_itm = ini_sys:r_bool_ex(section,"quest_item") local anm_itm = IsItem("anim",section) local tch_itm = s_find(section,"tch_") and true or false local bse_itm = s_find(section,"base") and true or false local main_itm = (not parent) or (parent and parent == section) if not (qst_itm and anm_itm and tch_itm and bse_itm and main_itm) then local x = ini_sys:r_float_ex(section,"inv_grid_x") local y = ini_sys:r_float_ex(section,"inv_grid_y") if (x and x ~= 0) and (y and y ~= 0) then sim:create(section, pos, lid, gid, AC_ID) end end end end) local function remove_backpack(id) local function itr(npc,itm) if (itm:section() == "itm_actor_backpack" or itm:section() == "itm_backpack") then alife_release_id(itm:id()) return end end db.actor:iterate_inventory(itr,db.actor) end CreateTimeEvent(0,"remove_backpack",1,remove_backpack,0) give_info("actor_made_wish_for_riches") give_info("actor_made_wish") return end action_list[5] = function() local se_actor = alife():actor() local data = utils_stpk.get_actor_data(se_actor) if (data) then data.specific_character = "actor_zombied" utils_stpk.set_actor_data(data,se_actor) end set_actor_true_community("zombied") give_info("actor_made_wish_immortal") give_info("actor_made_wish") -- local spawn_path = patrol("spawn_player_stalker") -- if (spawn_path) then -- local pos = spawn_path:point(0) -- local lvid = spawn_path:level_vertex_id(0) -- local gvid = spawn_path:game_vertex_id(0) -- local gg = game_graph() -- if (gvid and gg:valid_vertex_id(gvid)) then -- ChangeLevel(pos,lvid,gvid,VEC_ZERO) -- end -- end -- Teleports the player to a smashed open grave in the Great Swamp. -- Goodwill is increased with the Monolith and Zombified faction to ensure they aren't hostile. inc_faction_goodwill_to_actor(db.actor, nil, {"monolith", 5000}) inc_faction_goodwill_to_actor(db.actor, nil, {"zombied", 5000}) ChangeLevel(vector():set(266.99, 0.00, -131.07), 310937, 181, VEC_ZERO) return end -- Hide and disable the immortality wish if actor is in Zombified or Monolith factions. if (character_community(db.actor) == "actor_zombied" or character_community(db.actor) == "actor_monolith") then action_list[5] = nil ui_dyn_msg_box.multi_choice(action_list,"st_wish_1","st_wish_2","st_wish_3","st_wish_4","st_wish_99") else ui_dyn_msg_box.multi_choice(action_list,"st_wish_1","st_wish_2","st_wish_3","st_wish_4","st_wish_5","st_wish_99") end end function clear_logic(actor,npc,p) local st = db.storage[npc:id()] st.ini, st.ini_filename = xr_logic.get_customdata_or_ini_file(npc, "") st.active_section = nil st.active_scheme = nil st.section_logic = "logic" xr_logic.switch_to_section(npc,nil,nil) end function set_new_scheme_and_logic(actor,npc,p) local st = db.storage[npc:id()] st.ini_filename = ini_filename st.ini = ini_file(ini_filename) if not (st.ini) then printe("!ERROR: set_new_scheme_and_logic: can't find ini %s",ini_filename) return end -- Set new section logic st.section_logic = logic -- Select new active section local new_section = section or xr_logic.determine_section_to_activate(npc, st.ini, st.section_logic) -- Switch to new section xr_logic.switch_to_section(npc, st.ini, new_section) st.overrides = xr_logic.cfg_get_overrides(st.ini, new_section, npc) end function set_script_danger(actor,npc,p) xr_danger.set_script_danger(npc,p and tonumber(p[1]) or 5000) end function spawn_npc_at_position(actor,npc,p) if not (p) then return end local pos = vector():set(tonumber(p[2]),tonumber(p[3]),tonumber(p[4])) alife_create(p[1],pos,p[5],p[6]) end function kill_obj_on_job(actor,npc,p) local board = SIMBOARD local smart = p[1] and board and board.smarts_by_names[p[1]] local obj = smart and smart.npc_by_job_section["logic@"..p[2]] obj = obj and level.object_by_id(obj) if not obj or not obj:alive() then return false end local h = hit() h:bone("bip01_neck") h.power = 1 h.impulse = 1 h.direction = vec_sub(npc:position(), obj:position()) h.draftsman = npc h.type = hit.wound obj:hit(h) end function obj_at_job_switch_section(actor,npc,p) local board = SIMBOARD local smart = p[1] and board and board.smarts_by_names[p[1]] local obj = smart and smart.npc_by_job_section["logic@"..p[2]] obj = obj and level.object_by_id(obj) if not obj or not obj:alive() then return end local st = db.storage[obj:id()] if not (st) then return end xr_logic.switch_to_section(obj, st.ini, p[3]) end function change_visual(actor,npc,p) if (not axr_main) then return end local sobj = alife_object(npc:id()) if not (sobj) then return end if (axr_main) then CreateTimeEvent(sobj.id,"update_visual",1,update_visual,sobj.id,p[1]) end end function switch_offline(actor,npc,p) local se_obj = npc and alife_object(npc:id()) if (se_obj and se_obj:can_switch_offline()) then se_obj:switch_offline() end end ------------------- util functions function update_visual(id,vis) local se_npc = id and alife_object(id) if not (se_npc) then return true end if (se_npc.online) then se_npc:switch_offline() return false end if not (vis) then return true end local data = utils_stpk.get_stalker_data(se_npc) if (data) then data.visual_name = vis utils_stpk.set_stalker_data(data,se_npc) end return true end function up_start() --up.up_objects_spawn() --up.up_stalkers_spawn() end function up_freeplay() --up.freeplay_clean_territory() end function stop_sr_cutscene(actor,npc,p) local obj = db.storage[npc:id()] if(obj.active_scheme~=nil) then obj[obj.active_scheme].signals["cam_effector_stop"] = true end end function update_weather(actor, npc, p) if p and p[1] then if p[1] == "true" then level_weathers.get_weather_manager():select_weather(true) elseif p[1] == "false" then level_weathers.get_weather_manager():select_weather(false) end end end --X16 machine switch off function yan_gluk (actor, npc) local sound_obj_l = xr_sound.get_safe_sound_object( [[affects\psy_blackout_l]] ) local sound_obj_r = xr_sound.get_safe_sound_object( [[affects\psy_blackout_r]] ) sound_obj_l:play_no_feedback(db.actor, sound_object.s2d, 0, vector():set(-1, 0, 1), 1.0, 1.0) sound_obj_r:play_no_feedback(db.actor, sound_object.s2d, 0, vector():set( 1, 0, 1), 1.0, 1.0) level.add_cam_effector("camera_effects\\earthquake.anm", 1974, false, "") end function yan_saharov_message(actor, npc, p) local actor_comm = get_actor_true_community() if (not game_relations.is_factions_enemies(actor_comm,"ecolog")) then if (p[1] == 1) then news_manager.send_tip(db.actor, "st_yan_saharov_message", nil, "saharov", 15000, nil) db.actor:give_info_portion("labx16_find") elseif (p[1] == 2) and db.actor:object("bad_psy_helmet") then news_manager.send_tip(db.actor, "st_yan_saharov_message_2", nil, "saharov", 20000, nil) elseif (p[1] == 3) then news_manager.send_tip(db.actor, "st_yan_saharov_message_3", nil, "saharov", 15000, nil) elseif (p[1] == "free_upgrade") then news_manager.send_tip(db.actor, "st_yan_saharov_message_free_upgrade", nil, "saharov", 15000, nil) end end end --X18 dream function x18_gluk (actor, npc) level.add_pp_effector ("blink.ppe", 234, false) local sound_obj_l = xr_sound.get_safe_sound_object( [[affects\psy_blackout_l]] ) local sound_obj_r = xr_sound.get_safe_sound_object( [[affects\psy_blackout_r]] ) local snd_obj = xr_sound.get_safe_sound_object( [[affects\tinnitus3a]] ) snd_obj:play_no_feedback(db.actor, sound_object.s2d, 0, vector(), 1.0, 1.0) sound_obj_l:play_no_feedback(db.actor, sound_object.s2d, 0, vector():set(-1, 0, 1), 1.0, 1.0) sound_obj_r:play_no_feedback(db.actor, sound_object.s2d, 0, vector():set( 1, 0, 1), 1.0, 1.0) level.add_cam_effector("camera_effects\\earthquake.anm", 1974, false, "") end function end_yantar_dream(actor, npc) db.actor:give_info_portion("yantar_find_ghost_task_start") end function end_x18_dream(actor, npc) db.actor:give_info_portion("dar_x18_dream") end function end_radar_dream(actor, npc) db.actor:give_info_portion("bun_patrol_start") end function end_warlab_dream(actor, npc) db.actor:give_info_portion("end_warlab_dream") end function end_final_peace(actor, npc) db.actor:give_info_portion("end_final_peace") end --------------------------------------------------------- -- Sarcofag2 --------------------------------------------------------- function aes_earthshake (npc) local snd_obj = xr_sound.get_safe_sound_object([[ambient\earthquake]]) snd_obj:play_no_feedback(db.actor, sound_object.s2d, 0, vector(), 1.0, 1.0) level.add_cam_effector("camera_effects\\earthquake.anm", 1974, false, "") --set_postprocess ("scripts\\earthshake.ltx") end function oso_init_dialod () -- local oso = level_object_by_sid(osoznanie) -- db.actor:run_talk_dialog(oso) end function warlab_stop_particle(actor, npc, p) db.actor:stop_particles("anomaly2\\control_monolit_holo", "link") end function play_snd_from_obj(actor, npc, p) if p[1] and p[2] then local snd_obj = xr_sound.get_safe_sound_object(p[2]) local obj = level_object_by_sid(p[1]) if obj ~= nil then printf("can't find object with story id %s", tostring(p[1])) -- snd_obj:play_at_pos(obj, obj:position(), sound_object.s3d) snd_obj:play_no_feedback(obj, sound_object.s3d, 0, obj:position(), 1.0, 1.0) end end end function play_snd(actor, npc, p) if p[1] then local snd_obj = xr_sound.get_safe_sound_object(p[1]) --snd_obj:play(actor, p[2] or 0, sound_object.s2d) snd_obj:play_no_feedback(actor, sound_object.s2d, p[2] or 0, vector(), 1.0, 1.0) end end function erase_pstor_ctime(actor,npc,p) if not (p[1]) then return end save_ctime(db.actor,p[1],nil) end -- Shows progress bar health for last hit enemy with db.storage[id].show_health = true -- param 1: Story ID -- param 2: true or false; default is true. True will set db.storage[id].show_health = true while false will remove custom static from screen function show_health(actor,npc,p) if (p[2] == "false") then ui_enemy_health.cs_remove() else local id = get_story_object_id(p[1]) local st = id and db.storage[id] if (st) then st.show_health = true end end end function disable_monolith_zones(actor,npc,p) local remove_sections = { ["zone_monolith"] = true } local sim = alife() for i=1,65534 do local se_obj = sim:object(i) if (se_obj and remove_sections[se_obj:section_name()]) then alife_release(se_obj) end end end function disable_generator_zones(actor,npc,p) local remove_sections = { ["generator_torrid"] = true, ["generator_dust"] = true, ["generator_electra"] = true, ["generator_dust_static"] = true } local sim = alife() for i=1,65534 do local se_obj = sim:object(i) if (se_obj and remove_sections[se_obj:section_name()]) then alife_release(se_obj) end end end --OLD ARENA function bar_arena_hit(actor, npc) local h = hit() h.power = 0.01 h.direction = npc:direction() h.draftsman = db.actor h.impulse = 1 h.type = hit.wound npc:hit(h) end function bar_arena_introduce(actor, npc) if db.actor:has_info("bar_arena_pseudodog_choosen") then news_manager.send_tip(db.actor, "bar_arena_fight_pseudodog", nil, "arena", 24000, nil) elseif db.actor:has_info("bar_arena_snork_choosen") then news_manager.send_tip(db.actor, "bar_arena_fight_snork", nil, "arena", 30000, nil) elseif db.actor:has_info("bar_arena_bloodsucker_choosen") then news_manager.send_tip(db.actor, "bar_arena_fight_bloodsucker", nil, "arena", 30000, nil) elseif db.actor:has_info("bar_arena_burer_choosen") then news_manager.send_tip(db.actor, "bar_arena_fight_burer", nil, "arena", 52000, nil) elseif db.actor:has_info("bar_arena_savage_choosen") then news_manager.send_tip(db.actor, "bar_arena_fight_savage", nil, "arena", 34000, nil) end end function bar_arena_fight_begin(actor, npc) if db.actor:has_info("bar_arena_actor_lose") or db.actor:has_info("bar_arena_actor_victory") then return end news_manager.send_tip(db.actor, "bar_arena_fight_begin", nil, "arena") end function bar_arena_fight_10(actor, npc) news_manager.send_tip(db.actor, "bar_arena_fight_10", nil, "arena") end function bar_arena_fight_20(actor, npc) news_manager.send_tip(db.actor, "bar_arena_fight_20", nil, "arena") end function bar_arena_fight_30(actor, npc) news_manager.send_tip(db.actor, "bar_arena_fight_30", nil, "arena") end function bar_arena_fight_40(actor, npc) news_manager.send_tip(db.actor, "bar_arena_fight_40", nil, "arena") end function bar_arena_fight_50(actor, npc) news_manager.send_tip(db.actor, "bar_arena_fight_50", nil, "arena") end function bar_arena_fight_60(actor, npc) news_manager.send_tip(db.actor, "bar_arena_fight_60", nil, "arena") end function bar_arena_fight_70(actor, npc) news_manager.send_tip(db.actor, "bar_arena_fight_70", nil, "arena") end function bar_arena_fight_80(actor, npc) news_manager.send_tip(db.actor, "bar_arena_fight_80", nil, "arena") end function bar_arena_fight_90(actor, npc) news_manager.send_tip(db.actor, "bar_arena_fight_90", nil, "arena") end function bar_arena_check_lose(actor, npc) if db.actor:has_info("bar_arena_100_p") then if db.actor:has_info("bar_arena_fight_30") then db.actor:give_info_portion("bar_arena_actor_lose") news_manager.send_tip(actor, "bar_arena_fight_timeout", nil, "arena") end return end if db.actor:has_info("bar_arena_50_p") then if db.actor:has_info("bar_arena_fight_90") then db.actor:give_info_portion("bar_arena_actor_lose") news_manager.send_tip(actor, "bar_arena_fight_timeout", nil, "arena") end return end end function bar_arena_after_fight(actor, npc) if db.actor:has_info("bar_arena_actor_lose") or db.actor:has_info("bar_arena_actor_victory") then return end if db.actor:dont_has_info("bar_arena_actor_lose") then db.actor:give_info_portion("bar_arena_actor_victory") news_manager.send_tip(actor, "bar_arena_fight_victory", nil, "arena") else news_manager.send_tip(actor, "bar_arena_fight_lose", nil, "arena") end db.actor:give_info_portion("bar_arena_start_introduce") end function bar_arena_actor_afraid(actor, npc) news_manager.send_tip(db.actor, "bar_arena_actor_afraid", nil, "arena") end function bar_arena_actor_dead(actor, npc) news_manager.send_tip(db.actor, "bar_arena_fight_dead", nil, "arena") end --NEW ARENA function bar_arena_teleport (actor, npc) actor_effects.disable_effects_timer(100) --hide_hud_inventory() hide_hud_all() local box = get_story_object("bar_arena_inventory_box") if (box) then local function transfer_object_item(item) db.actor:transfer_item(item, box) end db.actor:inventory_for_each(transfer_object_item) end local spawn_items = {} if has_alife_info("bar_arena_fight_1") then table.insert(spawn_items, "novice_outfit") table.insert(spawn_items, "wpn_pm") table.insert(spawn_items, "ammo_9x18_pmm") table.insert(spawn_items, "ammo_9x18_pmm") --table.insert(spawn_items, "wpn_knife") elseif has_alife_info("bar_arena_fight_2") then table.insert(spawn_items, "stalker_outfit") table.insert(spawn_items, "wpn_mp5") table.insert(spawn_items, "ammo_9x19_pbp") --table.insert(spawn_items, "wpn_knife") elseif has_alife_info("bar_arena_fight_3") then table.insert(spawn_items, "stalker_outfit") table.insert(spawn_items, "wpn_bm16") table.insert(spawn_items, "ammo_12x70_buck") table.insert(spawn_items, "ammo_12x70_buck") --table.insert(spawn_items, "wpn_knife") elseif has_alife_info("bar_arena_fight_4") then table.insert(spawn_items, "stalker_outfit") table.insert(spawn_items, "wpn_ak74") table.insert(spawn_items, "ammo_5.45x39_ap") table.insert(spawn_items, "ammo_5.45x39_ap") --table.insert(spawn_items, "wpn_knife") table.insert(spawn_items, "bandage") table.insert(spawn_items, "bandage") elseif has_alife_info("bar_arena_fight_5") then table.insert(spawn_items, "wpn_abakan") table.insert(spawn_items, "ammo_5.45x39_ap") table.insert(spawn_items, "ammo_5.45x39_ap") table.insert(spawn_items, "ammo_5.45x39_ap") --table.insert(spawn_items, "wpn_knife") table.insert(spawn_items, "bandage") table.insert(spawn_items, "medkit") table.insert(spawn_items, "svoboda_light_outfit") elseif has_alife_info("bar_arena_fight_6") then table.insert(spawn_items, "wpn_groza") table.insert(spawn_items, "ammo_9x39_ap") table.insert(spawn_items, "ammo_9x39_ap") table.insert(spawn_items, "ammo_9x39_ap") --table.insert(spawn_items, "wpn_knife") table.insert(spawn_items, "specops_outfit") elseif has_alife_info("bar_arena_fight_7") then table.insert(spawn_items, "wpn_knife") table.insert(spawn_items, "bandage") table.insert(spawn_items, "grenade_f1") table.insert(spawn_items, "grenade_f1") elseif has_alife_info("bar_arena_fight_8") then table.insert(spawn_items, "wpn_g36") table.insert(spawn_items, "exo_outfit") table.insert(spawn_items, "ammo_5.56x45_ap") table.insert(spawn_items, "ammo_5.56x45_ap") table.insert(spawn_items, "ammo_5.56x45_ap") table.insert(spawn_items, "ammo_5.56x45_ap") --table.insert(spawn_items, "wpn_knife") end local k,v = 0,0 for k,v in pairs(spawn_items) do local se = alife_create(v, db.actor:position(), db.actor:level_vertex_id(), db.actor:game_vertex_id(), AC_ID) se_save_var( se.id, se:name(), "unpatched", true ) end end function bar_arena_weapon_slot (actor,npc,p) db.actor:activate_slot(tonumber(p[1]) or 1) end function bar_arena_teleport_2 (actor, npc) actor_effects.disable_effects_timer(100) --hide_hud_inventory() hide_hud_all() -- remove items from actor given to him by arena local box = get_story_object("bar_arena_inventory_box_2") if (box) then local function transfer_object_item(item) db.actor:transfer_item(item, box) end db.actor:inventory_for_each(transfer_object_item) end -- purge all marked items xr_zones.purge_arena_items("bar_arena") level.add_pp_effector ("blink.ppe", 234, false) db.actor:set_actor_position(patrol("t_walk_2"):point(0)) local dir = patrol("t_look_2"):point(0):sub(patrol("t_walk_2"):point(0)) db.actor:set_actor_direction(-dir:getH()) -- give actor back his items that were taken local box = get_story_object("bar_arena_inventory_box") if (box) then local function transfer_object_item(box,item) box:transfer_item(item, db.actor) end box:iterate_inventory_box(transfer_object_item,box) end end function purge_zone(actor,npc,p) if (p and p[1]) then xr_zones.purge_arena_items(p[1]) end end function clear_weather(actor,npc,p) end function actor_surge_immuned(actor,npc,p) save_var(db.actor,"surge_immuned",p[1] == "true" or nil) end function force_always_online(actor,npc,p) local squad = p[1] and get_story_squad(p[1]) if not (squad) then return end alife():set_switch_offline(squad.id,false) alife():set_switch_online(squad.id,true) end function set_smart_alarm_status(actor,npc,p) local smart = p[1] and SIMBOARD:get_smart_by_name(p[1]) if (smart) then smart:set_alarm() end end function setup_base_defense_fail_conditions(actor,npc,p) save_var(db.actor,"base_defense_level",level.name()) end --// AWR (Функция отправки сообщения об окончании времени, отключение ламп, закрытия UI) function awr_timer_msg_off(actor,npc,p) local npc_name = npc:section() if not (db.actor:has_info(string.format("awr_%s_dead", npc_name))) then bind_awr.dout('xr_effects', 'Timer off for %s', npc_name) actor_menu.set_item_news('fail', 'detail', "st_awr_timer_msg_off") bind_awr.Lamp(npc:section(), false) bind_awr.CloseDl() db.actor:disable_info_portion(string.format('awr_%s_access', npc_name)) else bind_awr.dout('xr_effects', "NPC %s is dead. Timer ignored", npc_name) end end